Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Enumerator MoveNext() returns 0

Why next code generates loop hangs?

var x = new
{
    Items = new List<int> { 1, 2, 3 }.GetEnumerator()
};

while (x.Items.MoveNext())
   Console.WriteLine(x.Items.Current);

If I get enumerator after x initialization, than everything works fine:

var x = new
{
    Items = new List<int> { 1, 2, 3 }
};

var enumerator = x.Items.GetEnumerator();

while (enumerator.MoveNext())
   Console.WriteLine(enumerator.Current);

Tried to decompile both code blocks, but don't understand the reason:

List<int> intList = new List<int>();
intList.Add(1);
intList.Add(2);
intList.Add(3);
var data1 = new \u003C\u003Ef__AnonymousType0<List<int>.Enumerator>(intList.GetEnumerator());
while (true)
{
   List<int>.Enumerator items = data1.Items;
   if (items.MoveNext())
   {
     items = data1.Items;
     Console.WriteLine(items.Current);
   }
   else
     break;
}
List<int> Items = new List<int>();
Items.Add(1);
Items.Add(2);
Items.Add(3);
var data2 = new \u003C\u003Ef__AnonymousType0<List<int>>(Items);
List<int>.Enumerator enumerator = data2.Items.GetEnumerator();
while (enumerator.MoveNext())
   Console.WriteLine(enumerator.Current);
like image 608
Metaller Avatar asked Aug 04 '26 20:08

Metaller


1 Answers

Because List's enumerator is a struct. In your first example, you're creating an enumerator object (somewhere, probably heap, doesn't matter) and every time you access it with .Items the enumerator gets copied onto the stack in your executing function. MoveNext mutates it and then the copied enumerator gets discarded. If it were a class, only the reference would be copied/discarded and the actual data modified but since it's a struct, you didn't modify the enumerator in var x { ... } at all. Enumerator.Current returns 0 because default(int) is zero but an exception would be possible, too.

In your second example you're creating a slot for the enumerator on the stack with var enumerator = x.Items.GetEnumerator(); and that slot gets accessed repeadedly without copies.

like image 79
Schmid Avatar answered Aug 07 '26 19:08

Schmid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!