Как работает foreach при циклическом просмотре результатов функции?

StackOverflow https://stackoverflow.com/questions/1632810

  •  06-07-2019
  •  | 
  •  

Вопрос

Предположим, у меня есть следующий код:

foreach(string str in someObj.GetMyStrings())
{
    // do some stuff
}

Будет someObj.GetMyStrings() вызываться на каждой итерации цикла?Было бы лучше вместо этого сделать следующее:

List<string> myStrings = someObj.GetMyStrings();
foreach(string str in myStrings)
{
    // do some stuff
}

?

Это было полезно?

Решение

Функция вызывается только один раз, чтобы вернуть 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 хитроумно, чтобы это сработало.

Другие советы

Нет..функция будет вызвана один раз, чтобы получить IEnumerable ..и затем будет повторный вызов MoveNext и Current.

GetMyStrings() повторно запускает объект типа IEnumerable.Среда выполнения знает, как с этим справиться.Он вызывает IEnumerable.GetEnumerator(), а затем для этого объекта enumerator вызывает MoveNext() и Current .

Просто чтобы закруглить вопрос на случай, если вы впадете в "все за одно и то же".;для(int x=0;x < ProvideCeiling() Обеспечить закрытие();x++) делает вызывайте эту функцию каждый раз.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top