rab*_*ens 3 c# ienumerator enumerator
考虑这个例子:
List<int> l = [1, 2, 3, 4, 5];
void DoSomethingWith(IEnumerator<int> e) {
Console.WriteLine(e.MoveNext());
Console.WriteLine(e.Current);
}
using(var e = l.GetEnumerator()) {
DoSomethingWith(e);
DoSomethingWith(e);
}
Run Code Online (Sandbox Code Playgroud)
该片段输出:
True
1
True
1
Run Code Online (Sandbox Code Playgroud)
我预计
True
1
True
2
Run Code Online (Sandbox Code Playgroud)
因为我传递了同一个枚举器。
为什么会这样呢?
List<T>.Enumerator返回的List<T>.GetEnumerator是 a,struct因此通过接口传递它会将其装箱(因此后续调用将使用从当前状态复制的不同实例)。例如以下内容:
using(var e = l.GetEnumerator())
{
e.MoveNext();
DoSomethingWith(e);
DoSomethingWith(e);
}
Run Code Online (Sandbox Code Playgroud)
将打印:
True
2
True
2
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,原始枚举器实际上并未重置。
您可以在 as 接口中显式指定类型using(这样您将装箱一次并传递枚举器的同一实例):
True
2
True
2
Run Code Online (Sandbox Code Playgroud)
或者更改方法以接受List<int>.Enumerator并传递它ref:
using(IEnumerator<int> e = l.GetEnumerator())
{
e.MoveNext();
DoSomethingWith(e);
DoSomethingWith(e);
}
Run Code Online (Sandbox Code Playgroud)
或者通过接口使用集合,因为IEnumerable<T>.GetEnumerator()是显式实现的,并且装箱将由实现处理:
void DoSomethingWith(ref List<int>.Enumerator e)
{
Console.WriteLine(e.MoveNext());
Console.WriteLine(e.Current);
}
var e = l.GetEnumerator();
DoSomethingWith(ref e);
DoSomethingWith(ref e);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
223 次 |
| 最近记录: |