The function's only called once, to return an IEnumerator<T>
; after that, the MoveNext()
method and the Current
property are used to iterate through the results:
foreach (Foo f in GetFoos())
{
// Do stuff
}
is somewhat equivalent to:
using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator())
{
while (iterator.MoveNext())
{
Foo f = iterator.Current;
// Do stuff
}
}
Note that the iterator is disposed at the end - this is particularly important for disposing resources from iterator blocks, e.g.:
public IEnumerable<string> GetLines(string file)
{
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
In the above code, you really want the file to be closed when you finish iterating, and the compiler implements IDisposable
cunningly to make that work.
GetMyStrings()
and see how many times the debugger stops there!