Could someone explain why this code is running in infinity loop? Why MoveNext()
return true
always?
var x = new { TempList = new List<int> { 1, 3, 6, 9 }.GetEnumerator() };
while (x.TempList.MoveNext())
{
Console.WriteLine("Hello World");
}
List<T>.GetEnumerator()
returns a mutable value type (List<T>.Enumerator
). You're storing that value in the anonymous type.
Now, let's have a look at what this does:
while (x.TempList.MoveNext())
{
// Ignore this
}
That's equivalent to:
while (true)
{
var tmp = x.TempList;
var result = tmp.MoveNext();
if (!result)
{
break;
}
// Original loop body
}
Now note what we're calling MoveNext()
on - the copy of the value which is in the anonymous type. You can't actually change the value in the anonymous type - all you've got is a property you can call, which will give you a copy of the value.
If you change the code to:
var x = new { TempList = (IEnumerable<int>) new List<int> { 1, 3, 6, 9 }.GetEnumerator() };
... then you'll end up getting a reference in the anonymous type. A reference to a box containing the mutable value. When you call MoveNext()
on that reference, the value inside the box will be mutated, so it'll do what you want.
For analysis on a very similar situation (again using List<T>.GetEnumerator()
) see my 2010 blog post "Iterate, damn you!".
See more on this question at Stackoverflow