Wie funktioniert foreach Arbeit, wenn sie durch Funktionsergebnisse Looping?
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
}
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