Pergunta

Suponha que eu tenho o seguinte código:

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

Will someObj.GetMyStrings() ser chamado em cada iteração do loop? Seria melhor para fazer o seguinte em vez disso:

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

?

Foi útil?

Solução

A função é chamado apenas uma vez, para retornar uma IEnumerator<T>; depois disso, o método MoveNext() ea propriedade Current são usados ??para percorrer os resultados:

foreach (Foo f in GetFoos())
{
    // Do stuff
}

é um tanto equivalente a:

using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator())
{
    while (iterator.MoveNext())
    {
        Foo f = iterator.Current;
        // Do stuff
    }
}
.

Note que o iterador está disposto no final - isto é particularmente importante para a eliminação recursos do iterador blocos, p.ex.:

public IEnumerable<string> GetLines(string file)
{
    using (TextReader reader = File.OpenText(file))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

No código acima, você realmente deseja que o arquivo a ser fechado quando você termina a iteração, e os implementos compilador IDisposable astuciosamente para fazer esse trabalho.

Outras dicas

Não .. a função será chamada uma vez para obter o IEnumerable .. e então não será repetido chamada para MoveNext e Current.

GetMyStrings () retuns um objeto do tipo IEnumerable. O tempo de execução sabe como lidar com isso. Ele chama IEnumerable.GetEnumerator () e depois no objeto enumerador chama MoveNext () e atual.

Apenas para completar a pergunta fora no caso de você cair em um "tudo por são os mesmos"; para (int x = 0; X faz chamar a função de cada vez.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top