General explainations for enumeration
IEnumerable is an interface, that is usually implemented by collection types in C#. For example List, Queue or Array.
IEnumerable provides a method GetEnumerator which returns an object of type IEnumerator.
The IEnumerator basically represents a "forward moving pointer" to elements in a collection.
IEnumerator has:
- the property
Current, which returns the object it currently points to (e.g. first object in your collection).
- a method
MoveNext, which moves the pointer to the next element. After calling it, Current will hold a reference to the second object in your collection. MoveNext will return false if there were no more elements in the collection.
Whenever a foreach loop is executed, the IEnumerator is retreived and MoveNext is called for each iteration - until it eventually returns false. The variable you define in your loop header, is filled with the IEnumerator's Current.
Compiling a foreach loop
thx to @Llama
This code...
List<int> a = new List<int>();
foreach (var val in a)
{
var b = 1 + val;
}
is transformed to something like this by the compiler:
List<int> list = new List<int>();
List<int>.Enumerator enumerator = list.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
int current = enumerator.Current;
int num = 1 + current;
}
} finally {
((IDisposable)enumerator).Dispose();
}
The quote
The query represented by this method is not executed until the object
is enumerated either by calling its GetEnumerator method directly or
by using foreach in Visual C#.
GetEnumerator is automatically called, as soon as you put your object into a foreach loop, for example. Of course, other functions, e.g. Linq queries, can also retreive the IEnumerator from your collection, by doing so either explicit (call GetEnumerator) or implicit in some sort of loop, like I did in my sample above.