C# .NET实现具有可空引用类型的IEnumerator

C# .NET实现具有可空引用类型的IEnumerator,c#,.net,ienumerator,nullable-reference-types,C#,.net,Ienumerator,Nullable Reference Types,从那以后,我真的很享受与你在一起的“空虚安全”。然而,在调整我的一个库以支持新功能时,我偶然发现了一个“问题”,我真的在任何地方都找不到答案。我看过微软的发行说明和.NET源代码,但运气不好 TL;DR:问题本质上是IEnumerator的Current属性是否应该声明为可为空的引用类型 假设以下是IEnumerator的实现: 公共类WebSocketClientEnumerator:IEnumerator其中TWebSocketClient:WebSocketClient { 私人网吧室;

从那以后,我真的很享受与你在一起的“空虚安全”。然而,在调整我的一个库以支持新功能时,我偶然发现了一个“问题”,我真的在任何地方都找不到答案。我看过微软的发行说明和.NET源代码,但运气不好

TL;DR:问题本质上是
IEnumerator
Current
属性是否应该声明为可为空的引用类型

假设以下是
IEnumerator
的实现:

公共类WebSocketClientEnumerator:IEnumerator其中TWebSocketClient:WebSocketClient
{
私人网吧室;
私人国际库林德斯;
私人TWebSocketClient?curCli;
公共WebSocketClientEnumerator(WebSocketRoom室)
{
这个房间=房间;
curIndex=-1;
curCli=默认值(TWebSocketClient);
}
公共图书馆
{
如果(++curIndex>=room.Count)
{
返回false;
}
其他的
{
curCli=房间[curIndex];
}
返回true;
}
public void Reset(){curIndex=-1;}
void IDisposable.Dispose(){}
public TWebSocketClient?当前
{
获取{return curCli;}
}
对象IEnumerator.Current
{
获取{返回当前;}
}
}
并假设以下代码使用枚举器:

public class WebSocketRoom<TWebSocketClient> : ICollection<TWebSocketClient> where TWebSocketClient : WebSocketClient
{
    // ...

    public void UseEnumerator()
    {
        var e = new WebSocketClientEnumerator<TWebSocketClient>(this);
        bool hasNext = e.MoveNext();
        if (hasNext)
        {
            WebSocketClient c = e.Current; // <= Warning on this line
        }
    }

    // ...
}
公共类WebSocketRoom:ICollection其中TWebSocketClient:WebSocketClient
{
// ...
public void UseEnumerator()
{
var e=新的WebSocketClientEnumerator(此);
bool hasNext=e.MoveNext();
如果(下一步)
{

WebSocketClient c=e.Current;//我绝对建议将其声明为not null版本。该声明指出,在
curCli
实际为null的情况下定义了该行为。我认为,在这些情况下,任何阅读
Current
的人的代码中都有bug,最好通过e例外……这很容易做到:

public TWebSocketClient Current=>curCli??
抛出新的InvalidOperationException(“当前状态下不应使用Current”);
当返回
false
时,您可能希望将
curCli
设置为
null
,这样,如果在耗尽枚举器后代码访问
Current
,也会引发异常


在这一点上,我认为您的代码比编译器为
生成的代码要好,因为它不会抛出异常。

是的,我没有想到会引发错误,但它实际上很有意义,我还认为在
MoveNext()之后读取
Current
返回false是客户端代码中的一个错误。打得好!Ty!
public class WebSocketRoom<TWebSocketClient> : ICollection<TWebSocketClient> where TWebSocketClient : WebSocketClient
{
    // ...

    public void UseEnumerator()
    {
        var e = new WebSocketClientEnumerator<TWebSocketClient>(this);
        bool hasNext = e.MoveNext();
        if (hasNext)
        {
            WebSocketClient c = e.Current; // <= Warning on this line
        }
    }

    // ...
}