To implement collection, I have to complete GeEnumerator(). But the return type of this function is IEnumerator. How can it be done ? For example..
class MyList : IEnumerable, IEnumerator
{
private int[] array;
int positino = -1;
public IEnumerator GetEnumerator()
{
for(int i = 0 ; i < array.Length; ++i)
{
yield return array[i];
}
}
}
array[i] is integer not IEnumerator type. How can this function return integer?
It doesn't, it
yield return
s an integer. This means that it can be compiled into a method that returnsIEnumerable
,IEnumerable<int>
,IEnumerator
orIEnumerator<int>
depending on which your method says it returns.The
yield
keyword is a convenience that allows for the creation of an enumerator with the appropriateMoveNext()
,Current
, andDispose
, and if it's an enumerable then the appropriateGetEnumerator
too.Looking at your method:
Then this is something that compiles, though to really work it needs more to actually assign something to
array
.When we compile it, it has the same result as if we'd written:
The main difference is that
En
and its fields would all have names that aren't valid C# names but are valid .NET names, so it can't clash with any names a programmer used.This has a bit more to it than it needs. It implements
IEnumerator<object>
as well asIEnumerator
, but then that means the compiler can just have logic forIEnumerable<T>
and useobject
for theT
for the non-generic type rather than having separate logic._state
is more complicated than necessary, but if theyield
-using method was more complicated than a single loop, then different values for_state
would allow it to keep track of which part of thatyield
-using method it was corresponding with.In all it's done a good job of implementing
IEnumerator
. It's a bit larger than if you were to hand-code one (and obviously larger than if you'd just usedreturn array.GetEnumerator();
), but not a lot larger, but conversely theyield
-using method is a lot shorter and often these methods are simpler. This is even more so in cases where e.g. you have ausing
block in theyield
-using method, which gets turned into the appropriate clean-up in the enumerator'sDispose()
.