Below is the custom class I made:
class B : IEnumerable
{
int[] data = { 0, 1, 2, 3, 4 };
public IEnumerator GetEnumerator()
{
Console.WriteLine("Called");
return new BEnumerator(this);
}
private class BEnumerator : IEnumerator
{
private B instance;
private int position = -1;
public BEnumerator(B inst)
{
this.instance = inst;
}
public object Current
{
get
{
return instance.data[position];
}
}
public bool MoveNext()
{
position++;
return (position < instance.data.Length);
}
public void Reset()
{
position = -1;
}
}
}
if we iterates through foreach:
B b = new B();
foreach (var item in b)
{
Console.WriteLine(item);
}
foreach (var item in b)
{
Console.WriteLine(item);
}
and the ouput is
called
0
1
2
3
4
called
0
1
2
3
4
we can see that GetEnumerator() was called twice since we use two foreach loop, each foreach call GetEnumerator() once, fair enough.
But if we modified the iterator as
public IEnumerator GetEnumerator()
{
yield return data[0];
yield return data[1];
yield return data[2];
yield return data[3];
yield return data[4];
}
it can easily be seen that GetEnumerator() will be called five times to get each value. So how come GetEnumerator() is called only once and sometimes multiple times, which is inconsistent?
P.S I know the fact that if you run the code with yield, the result is the same and GetEnumerator() seems to be called twice, but because yield is special, which makes the whole method seems to be only called once for every foreach, but the method has to be called multiple times in the background (GetEnumerator() will be called 10 times in this case)