Функция вызывается только один раз, чтобы вернуть IEnumerator<T>
; после этого метод MoveNext()
и свойство Current
используются для итерации результатов:
foreach (Foo f in GetFoos())
{
// Do stuff
}
в некоторой степени эквивалентно:
using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator())
{
while (iterator.MoveNext())
{
Foo f = iterator.Current;
// Do stuff
}
}
Обратите внимание, что итератор расположен в конце - это особенно важно для удаления ресурсов из блоков итератора, например ::
public IEnumerable<string> GetLines(string file)
{
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
В приведенном выше коде вы действительно хотите, чтобы файл был закрыт после завершения итерации, и компилятор хитро реализует IDisposable
, чтобы заставить это работать.