600 Stimmen

Was bedeutet "yield break;" in C#?

Ich habe diese Syntax in MSDN gesehen: yield break aber ich weiß nicht, was es bewirkt. Weiß es jemand?

4 Stimmen

Yield return macht eine Backing-Liste überflüssig, d. h. Sie müssen nicht so etwas codieren wie MyList.Add(...) einfach tun yield return ... . Wenn Sie die Schleife vorzeitig verlassen und die virtuelle Backing-Liste zurückgeben müssen, verwenden Sie yield break;

636voto

Damir Zekić Punkte 15070

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.

13 Stimmen

Könnte es einfach sein break anstelle von yield break in Ihrem obigen Beispiel? Der Compiler beschwert sich nicht darüber.

101 Stimmen

@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.

0 Stimmen

@DamirZekic, schließt der Iterator im Falle eines Bruchs alle Zyklen ab?

75voto

Brian Punkte 115257

Beendet einen Iterator-Block (sagt z. B., dass es keine weiteren Elemente in der IEnumerable gibt).

4 Stimmen

Mit [+1] -- obwohl es akademisch gesehen keine Iteratoren in .NET gibt. nur Enumeratoren (eine Richtung, vorwärts.)

0 Stimmen

@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

0 Stimmen

@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.

34voto

Trap Punkte 11603

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;
    }
}

32voto

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.

18voto

John ClearZ Punkte 872

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.com

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.

Powered by:

X