Как работает foreach при циклическом просмотре результатов функции? - PullRequest
31 голосов
/ 27 октября 2009

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

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

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

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

Ответы [ 4 ]

47 голосов
/ 27 октября 2009

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

18 голосов
/ 27 октября 2009

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

3 голосов
/ 27 октября 2009

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

0 голосов
/ 09 ноября 2017

Просто для округления вопроса на случай, если вы попадете в «все для того же»; for (int x = 0; x вызывает вызов функции каждый раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...