Consider this example:
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);
}
This snippet outputs:
True
1
True
1
I expect
True
1
True
2
because I pass in the same enumerator.
Why is this the case?
List<T>.Enumeratorreturned byList<T>.GetEnumeratoris astructso passing it by interface will box it (so subsequent invocations will work with different instances copied from the current state). For example the following:Will print:
So as you can see the original enumerator is not actually reset.
You can either specify the type explicitly in the
usingas interface (so you will box one time and pass the same instance of the enumerator):Or change the method to accept
List<int>.Enumeratorand pass it byref:Or work with collection via interface, since
IEnumerable<T>.GetEnumerator()is implemented explicitly and the boxing will be handled by the implementation: