Despite the fact, that IEnumerator.Reset
method should never be used I found strange behavior of the method implementation within List<T>
.
No matter how you examine the .NET Framework Source Code (tried with reference source and ILSpy) the method is implemented as following:
void System.Collections.IEnumerator.Reset() {
if (version != list._version) {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
index = 0;
current = default(T);
}
However, it looks like the method is never called at all! Consider the code:
var list = new List<int>(1) { 3 };
using (var e = list.GetEnumerator())
{
Console.WriteLine(e.MoveNext());
Console.WriteLine(e.Current);
((IEnumerator)e).Reset();
Console.WriteLine(e.MoveNext());
Console.WriteLine(e.Current);
}
It's pretty clear, that it should print True
and 3
twice. Instead of that the result is
True
3
False
0
Any simple explanation I'm missing?
Yes: you're boxing the
List.Enumerator
here: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:
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
orIEnumerator<int>
to start with. Then it will be boxed once, and theReset
method will mutate the boxed value: