使用枚举器实例化列表
Instantiation of List with Enumerator
我在代码片段中看到了这一行,想知道它的用途
var item = new List<int>.Enumerator();
这是做什么的?
我去编码了解更多,这就是我发现的
所以 var item = new List<int>.Enumerator();
return 您 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;
}
这是非常无用和错误的东西...
第一个问题应该是List<T>.Enumerator
是什么...它是List<T>
的一个支持class实现了IEnumerator<T>
接口(用于枚举一个集合,例如 foreach
)。 For performance reasons it is a struct
instead of being a class
。作为 struct
有一个预定义的 public 无参数构造函数(您正在使用的构造函数)。它甚至有一个带有一个参数 (List<T> list
) 的 internal
构造函数,用于设置一些必要的内部字段(最重要的是对创建它的 List<>
的引用)。此构造函数由 List<>.GetEnumerator()
.
使用
现在,如果你按照你写的去做,你将创建一个 "incomplete" Enumerator
。 item.Current
将 "work"(返回 default(T)
),但如果您尝试执行 item.MoveNext()
,您将得到 NullReferenceException
。如果你想要 IEnumerator
用于 "empty" 集合,最好这样做:
var item = Enumerable.Empty<int>().GetEnumerator();
为什么List<T>.Enumerator
是public
而不是private
或internal
... 有点复杂。 List<T>
实现了 IEnumerable<T>
和 IEnumerable
,因此它必须至少有两个具有这些签名的方法:
IEnumerator<T> IEnumerable<T>.GetEnumerator()
和
IEnumerator IEnumerable.GetEnumerator()
但出于性能原因,它将它们实现为显式实现(因此隐藏它们),并实现第三种方法:
public Enumerator GetEnumerator()
那个 returns 一个 struct Enumerator
...现在,由于 foreach
的工作原理,这第三个 public 方法将成为 foreach
.为什么这个?因为通过其接口之一使用的 struct
(在本例中为 IEnumerator<T>
或 IEnumerator
)被装箱(这会减慢它的速度)...但是如果 struct
直接使用(通过其public Enumerator GetEnumerator()
)方法,没有装箱,性能好一点......微软程序员在List<>
性能上付出了110%:-)
我在代码片段中看到了这一行,想知道它的用途
var item = new List<int>.Enumerator();
这是做什么的?
我去编码了解更多,这就是我发现的
所以 var item = new List<int>.Enumerator();
return 您 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;
}
这是非常无用和错误的东西...
第一个问题应该是List<T>.Enumerator
是什么...它是List<T>
的一个支持class实现了IEnumerator<T>
接口(用于枚举一个集合,例如 foreach
)。 For performance reasons it is a struct
instead of being a class
。作为 struct
有一个预定义的 public 无参数构造函数(您正在使用的构造函数)。它甚至有一个带有一个参数 (List<T> list
) 的 internal
构造函数,用于设置一些必要的内部字段(最重要的是对创建它的 List<>
的引用)。此构造函数由 List<>.GetEnumerator()
.
现在,如果你按照你写的去做,你将创建一个 "incomplete" Enumerator
。 item.Current
将 "work"(返回 default(T)
),但如果您尝试执行 item.MoveNext()
,您将得到 NullReferenceException
。如果你想要 IEnumerator
用于 "empty" 集合,最好这样做:
var item = Enumerable.Empty<int>().GetEnumerator();
为什么List<T>.Enumerator
是public
而不是private
或internal
... 有点复杂。 List<T>
实现了 IEnumerable<T>
和 IEnumerable
,因此它必须至少有两个具有这些签名的方法:
IEnumerator<T> IEnumerable<T>.GetEnumerator()
和
IEnumerator IEnumerable.GetEnumerator()
但出于性能原因,它将它们实现为显式实现(因此隐藏它们),并实现第三种方法:
public Enumerator GetEnumerator()
那个 returns 一个 struct Enumerator
...现在,由于 foreach
的工作原理,这第三个 public 方法将成为 foreach
.为什么这个?因为通过其接口之一使用的 struct
(在本例中为 IEnumerator<T>
或 IEnumerator
)被装箱(这会减慢它的速度)...但是如果 struct
直接使用(通过其public Enumerator GetEnumerator()
)方法,没有装箱,性能好一点......微软程序员在List<>
性能上付出了110%:-)