【问题标题】:Instantiation of List with Enumerator使用枚举器实例化列表
【发布时间】:2018-05-18 06:39:40
【问题描述】:

我在一段代码中看到了这行代码,想知道它的用途

var item = new List<int>.Enumerator();

这是做什么的?

【问题讨论】:

标签: c# list enumerator


【解决方案1】:

这是一个非常无用和错误的东西......

第一个问题应该是List&lt;T&gt;.Enumerator是什么...它是List&lt;T&gt;的一个支持类,它实现了IEnumerator&lt;T&gt;接口(用于枚举集合的接口,例如foreach使用的)。 For performance reasons it is a struct instead of being a class。作为struct 具有预定义的公共无参数构造函数(您正在使用的构造函数)。它甚至还有一个internal 构造函数,它带有一个参数(List&lt;T&gt; list),用于设置一些必要的内部字段(最重要的是对创建它的List&lt;&gt; 的引用)。这个构造函数被List&lt;&gt;.GetEnumerator()使用。

现在,如果你按照你写的去做,你会创建一个“不完整的”Enumeratoritem.Current 将“工作”(返回default(T)),但如果您尝试执行item.MoveNext(),您将得到NullReferenceException。如果您想要一个“空”集合的IEnumerator,最好这样做:

var item = Enumerable.Empty<int>().GetEnumerator();

因为List&lt;T&gt;.Enumeratorpublic 而不是privateinternal 的原因...有点复杂。 List&lt;T&gt; 实现了IEnumerable&lt;T&gt;IEnumerable,所以它必须至少有两个带有这些签名的方法:

IEnumerator<T> IEnumerable<T>.GetEnumerator()

IEnumerator IEnumerable.GetEnumerator()

但出于性能原因,它将它们实现为显式实现(因此隐藏它们),并实现第三种方法:

public Enumerator GetEnumerator()

返回struct Enumerator... 现在,感谢foreach 的工作方式,这第三个公共方法将是foreach 使用的方法。为什么这个?因为通过其接口之一使用的struct(在这种情况下为IEnumerator&lt;T&gt;IEnumerator)被装箱(这会稍微减慢它的速度)......但是如果直接使用struct(通过它的@987654357 @) 方法,没有装箱,性能稍微好一点...微软程序员在List&lt;&gt; 性能上给出了110% :-)

【讨论】:

    【解决方案2】:

    我去代码了解更多,这是我找到的

    所以var item = new List&lt;int&gt;.Enumerator(); 返回Enumerable 结构的实例,它将映射到您的列表。由于 Enumerator 是结构,它将使用默认值初始化其成员,在这种情况下,基于代码它将列表初始化为 null。详情可以看code of list.

    在这种情况下,不存在列表实例,所以如果您访问这样的任何方法

    var item = new List<int>.Enumerator();
    item.Currnet or item.MovNext()
    

    主要抛出异常或默认 int 你必须尝试一下。

    详情:https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs

     public struct Enumerator : IEnumerator<T>, System.Collections.IEnumerator
            {
                private List<T> list;
                private int index;
                private int version;
                private T current;
    
                internal Enumerator(List<T> list) {
                    this.list = list;
                    index = 0;
                    version = list._version;
                    current = default(T);
                }
    
                public void Dispose() {
                }
    
                public bool MoveNext() {
    
                    List<T> localList = list;
    
                    if (version == localList._version && ((uint)index < (uint)localList._size)) 
                    {                                                     
                        current = localList._items[index];                    
                        index++;
                        return true;
                    }
                    return MoveNextRare();
                }
    
                private bool MoveNextRare()
                {                
                    if (version != list._version) {
                        ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
                    }
    
                    index = list._size + 1;
                    current = default(T);
                    return false;                
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-30
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多