List<T>.Enumerator IEnumerator.Reset() method implementation

时光毁灭记忆、已成空白 提交于 2019-12-04 07:37:53
Jon Skeet

Any simple explanation I'm missing?

Yes: you're boxing the List.Enumerator here:

((IEnumerator)e).Reset();

That takes a copy of the existing one and resets it - leaving the original in one piece.

To reset the actual enumerator, you'd need something like this:

var list = new List<int>(1) { 3 };
var e = list.GetEnumerator();
// Can't use "ref" with a using statement
try
{
    Console.WriteLine(e.MoveNext());
    Console.WriteLine(e.Current);

    Reset(ref e);

    Console.WriteLine(e.MoveNext());
    Console.WriteLine(e.Current);
}
finally
{
    e.Dispose();
}

static void Reset<T>(ref T enumerator) where T : IEnumerator
{
    enumerator.Reset();
}

It's tricky because it uses explicit interface implementation.

I haven't tested it, but I think that should work for you. Obviously it's a bad idea to do this...

EDIT: Alternatively, just change your variable type to IEnumerator or IEnumerator<int> to start with. Then it will be boxed once, and the Reset method will mutate the boxed value:

var list = new List<int>(1) { 3 };
using (IEnumerator e = list.GetEnumerator())
{
    Console.WriteLine(e.MoveNext());
    Console.WriteLine(e.Current);

    e.Reset();

    Console.WriteLine(e.MoveNext());
    Console.WriteLine(e.Current);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!