Frage

Angenommen, ich habe den folgenden Code:

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

Wird someObj.GetMyStrings() bei jeder Iteration der Schleife aufgerufen werden? Wäre es besser, das zu tun folgenden statt:

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

War es hilfreich?

Lösung

Die Funktion ist nur einmal aufgerufen, ein IEnumerator<T> zurückzukehren; danach werden die MoveNext() Verfahren und die Current Eigenschaft verwendet, um durch die Ergebnisse iterieren:

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

ist etwas äquivalent zu:

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

Beachten Sie, dass der Iterator am Ende angeordnet ist - dies ist besonders wichtig für Ressourcen aus Iterator Blöcken entsorgen, z.

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

In dem obigen Code, wollen Sie wirklich die Datei geschlossen werden, wenn Sie Iteration zu beenden, und die Compiler implementiert IDisposable listig, dass die Arbeit zu machen.

Andere Tipps

Nein .. wird die Funktion einmal aufgerufen, um das IEnumerable zu bekommen .. und dann wird es wiederholt Aufruf von Movenext und Current wird.

GetMyStrings () Retuns ein Objekt vom Typ IEnumerable. Die Laufzeit weiß, wie er damit umgehen. Er fordert IEnumerable.GetEnumerator () und dann auf diesem Enumeratorobjekt ruft Movenext () und Strom.

Sie einfach die Frage abzurunden, falls Sie fallen in ein „alle für die die gleichen sind“;     for (int x = 0; x hat rufen Sie die Funktion jedes Mal.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top