Ich habe diese Syntax in MSDN gesehen: yield break
aber ich weiß nicht, was es bewirkt. Weiß es jemand?
Könnte es einfach sein break
anstelle von yield break
in Ihrem obigen Beispiel? Der Compiler beschwert sich nicht darüber.
Ich habe diese Syntax in MSDN gesehen: yield break
aber ich weiß nicht, was es bewirkt. Weiß es jemand?
Er gibt an, dass ein Iterator zu Ende gegangen ist. Sie können sich vorstellen yield break
als return
Anweisung, die keinen Wert zurückgibt.
Wenn Sie beispielsweise eine Funktion als Iterator definieren, kann der Körper der Funktion wie folgt aussehen:
for (int i = 0; i < 5; i++)
{
yield return i;
}
Console.Out.WriteLine("You will see me");
Beachten Sie, dass, nachdem die Schleife alle Zyklen durchlaufen hat, die letzte Zeile ausgeführt wird und Sie die Meldung in Ihrer Konsolenanwendung sehen werden.
Oder wie hier mit yield break
:
int i = 0;
while (true)
{
if (i < 5)
{
yield return i;
}
else
{
// note that i++ will not be executed after this
yield break;
}
i++;
}
Console.Out.WriteLine("Won't see me");
In diesem Fall wird die letzte Anweisung nie ausgeführt, da wir die Funktion vorzeitig verlassen haben.
Könnte es einfach sein break
anstelle von yield break
in Ihrem obigen Beispiel? Der Compiler beschwert sich nicht darüber.
@orad eine einfache break
würde in diesem Fall die Schleife anhalten, aber die Ausführung der Methode nicht abbrechen, so dass die letzte Zeile ausgeführt würde und der "Won't see me text" tatsächlich zu sehen wäre.
Mit [+1] -- obwohl es akademisch gesehen keine Iteratoren in .NET gibt. nur Enumeratoren (eine Richtung, vorwärts.)
@Shaun Wilson, aber mit yield
Schlüsselwort können Sie eine Sammlung in beide Richtungen durchlaufen, außerdem können Sie jedes nächste Element der Sammlung nehmen, das nicht in einer Reihe steht
@monstr können Sie Sammlungen beliebig iterieren und benötigen keine yield
Ich sage nicht, dass Sie falsch liegen, ich sehe, was Sie vorschlagen; aber akademisch gesehen gibt es in .NET keine Iteratoren, sondern nur Aufzählungszeichen (eine Richtung, vorwärts) - im Gegensatz zu stdc++ gibt es kein "generisches Iterator-Framework", das im CTS/CLR definiert ist. LINQ hilft, die Lücke mit Erweiterungsmethoden zu schließen, die Folgendes nutzen yield return
und auch Rückrufmethoden , aber es handelt sich um Erweiterungsmethoden erster Klasse, nicht um Iteratoren erster Klasse. IEnumerable
kann selbst nicht in eine andere Richtung als vorwärts in Bezug auf den Aufrufer iterieren.
Sagt dem Iterator, dass er das Ende erreicht hat.
Ein Beispiel:
public interface INode
{
IEnumerable<Node> GetChildren();
}
public class NodeWithTenChildren : INode
{
private Node[] m_children = new Node[10];
public IEnumerable<Node> GetChildren()
{
for( int n = 0; n < 10; ++n )
{
yield return m_children[ n ];
}
}
}
public class NodeWithNoChildren : INode
{
public IEnumerable<Node> GetChildren()
{
yield break;
}
}
yield
macht grundsätzlich eine IEnumerable<T>
Methode verhält sich ähnlich wie ein kooperativ (im Gegensatz zu präemptiv) geplanter Thread.
yield return
ist wie ein Thread, der eine "schedule"- oder "sleep"-Funktion aufruft, um die Kontrolle über die CPU abzugeben. Genau wie ein Thread, kann die IEnumerable<T>
Methode die Kontrolle an dem Punkt unmittelbar danach wieder, wobei alle lokalen Variablen die gleichen Werte haben wie vor der Aufgabe der Kontrolle.
yield break
ist wie ein Thread, der das Ende seiner Funktion erreicht und beendet wird.
Man spricht von einem "Zustandsautomaten", aber ein Zustandsautomat ist alles, was ein "Thread" wirklich ist. Ein Thread hat einen bestimmten Zustand (d.h. Werte lokaler Variablen), und jedes Mal, wenn er geplant wird, führt er eine oder mehrere Aktionen aus, um einen neuen Zustand zu erreichen. Der springende Punkt bei yield
ist, dass im Gegensatz zu den uns vertrauten Betriebssystem-Threads der Code, der ihn verwendet, in der Zeit eingefroren ist, bis die Iteration manuell fortgesetzt oder beendet wird.
Yield break ist nur ein Weg, um zu sagen, dass man zum letzten Mal zurückkehrt und keinen Wert zurückgibt
z.B.
// returns 1,2,3,4,5
IEnumerable<int> CountToFive()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
yield return 5;
yield break;
yield return 6;
yield return 7;
yield return 8;
yield return 9;
}
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
4 Stimmen
Yield return macht eine Backing-Liste überflüssig, d. h. Sie müssen nicht so etwas codieren wie
MyList.Add(...)
einfach tunyield return ...
. Wenn Sie die Schleife vorzeitig verlassen und die virtuelle Backing-Liste zurückgeben müssen, verwenden Sieyield break;