yield (C#-Referenz)
Wenn Sie das yield-Schlüsselwort in einer Anweisung verwenden, geben Sie an, dass die - Methode, der Operator oder der get Accessor, in dem sie angezeigt wird, ein Iterator ist.Sie verwenden einen Iterator, um eine benutzerdefinierte Iteration über einer Auflistung auszuführen.Im folgenden Beispiel werden die beiden Formen der Anweisung yield an.
yield return <expression>;
yield break;
Hinweise
Sie verwenden eine yield return-Anweisung, um jedes Element einzeln zurückzugeben.
Sie verwenden eine Iteratormethode, indem Sie eine foreach-Anweisung oder Eine LINQ-Abfrage verwenden.Jede Iteration der Schleife foreach ruft die Iteratormethode auf.Wenn eine yield return-Anweisung in der Iteratormethode erreicht ist, wird expression zurückgegeben, und die aktuelle Position im Code wird beibehalten.Die Ausführung von diesem Speicherort beim nächsten Mal neu gestartet, dass die Iteratorfunktion aufgerufen wird.
Sie können eine yield break-Anweisung verwenden, um die Iteration zu beenden.
Weitere Informationen zu Iteratoren finden Sie unter Iteratoren (C# und Visual Basic).
Iteratormethoden und -get-Accessoren
Die Deklaration eines Iterators muss die folgenden Anforderungen erfüllen:
Der Rückgabetyp muss IEnumerable, IEnumerable<T>, IEnumerator oder IEnumerator<T> sein.
Die Deklaration kann keine Referenz oder Auschecken-Parameter haben.
Eine implizite Konvertierung muss vom Typ des Ausdrucks in der yield return-Anweisung an den Rückgabetyp des Iterators vorhanden sind.
Sie können eine yield return oder yield break-Anweisung nicht in Methoden enthalten, die die folgenden Eigenschaften aufweisen:
Anonyme Methoden.Weitere Informationen finden Sie unter Anonyme Methoden (C#-Programmierhandbuch).
Methoden, die unsichere Blöcke enthalten.Weitere Informationen finden Sie unter unsafe (C#-Referenz).
Ausnahmebehandlung
Eine yield return-Anweisung kann nicht in einen try/catch-Block befinden.Eine yield return-Anweisung kann sich im try-Block einer TRY--abschließendanweisung befinden.
Eine yield break-Anweisung kann sich in einem try-Block oder in einem catch-Block jedoch nicht in einem finally-Block befinden.
Wenn der foreach Text (außerhalb der Iteratormethode) eine Ausnahme auslöst, wird ein finally-Block in der Iteratormethode ausgeführt.
Technische Implementierung
Der folgende Code gibt IEnumerable<string> aus einer Iteratormethode zurück und durchläuft dann von der übergeordneten durch.
IEnumerable<string> elements = MyIteratorMethod();
foreach (string element in elements)
{
…
}
Der Aufruf MyIteratorMethod führt nicht den Text der Methode aus.Stattdessen beim Aufruf IEnumerable<string> in die elements-Variable.
Auf einer Iteration der Schleife foreach, wird die MoveNext-Methode für elements aufgerufen.Dieser Aufruf wird der Text von MyIteratorMethod aus, bis die folgende Anweisung yield return erreicht ist.Der Ausdruck, der durch die yield return-Anweisung zurückgegeben wird, bestimmt nicht nur den Wert der element-Variable für die Konsumierung durch den Schleifentext jedoch auch die Current-Eigenschaft von Elementen, die IEnumerable<string> ist.
Klicken Sie in der nächsten Iteration foreach-Schleife, setzt die Ausführung des Iteratortexts der, in denen diese durch unterzogen fort und erneut angehalten wird, wenn sie eine yield return-Anweisung erreicht.Die foreach-Schleife werden abgeschlossen, wenn das Ende der Iteratormethode oder der yield break-Anweisung erreicht wird.
Beispiel
Das folgende Beispiel enthält eine yield return-Anweisung, die innerhalb einer for-Schleife ist.Jede Iteration des foreach-Anweisungstexts in Process erstellt einen Aufruf der Power Iteratorfunktion.Jeder Aufruf der Iteratorfunktion wechselt zur nächsten Ausführung der yield return-Anweisung über, die während der nächsten Iteration der Schleife for auftritt.
Der Rückgabetyp der Iteratormethode ist IEnumerable, die ein Iteratorschnittstellentyp ist.Wenn die Iteratormethode aufgerufen wird, gibt sie ein aufzählbares Objekt zurück, das die Potenzen einer Zahl enthält.
public class PowersOf2
{
static void Main()
{
// Display powers of 2 up to the exponent of 8:
foreach (int i in Power(2, 8))
{
Console.Write("{0} ", i);
}
}
public static System.Collections.IEnumerable Power(int number, int exponent)
{
int result = 1;
for (int i = 0; i < exponent; i++)
{
result = result * number;
yield return result;
}
}
// Output: 2 4 8 16 32 64 128 256
}
Im folgenden Beispiel wird ein get Accessor, der ein Iterator ist.Im Beispiel gibt jede yield return-Anweisung eine Instanz einer benutzerdefinierten Klasse zurück.
public static class GalaxyClass
{
public static void ShowGalaxies()
{
var theGalaxies = new Galaxies();
foreach (Galaxy theGalaxy in theGalaxies.NextGalaxy)
{
Debug.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears.ToString());
}
}
public class Galaxies
{
public System.Collections.Generic.IEnumerable<Galaxy> NextGalaxy
{
get
{
yield return new Galaxy { Name = "Tadpole", MegaLightYears = 400 };
yield return new Galaxy { Name = "Pinwheel", MegaLightYears = 25 };
yield return new Galaxy { Name = "Milky Way", MegaLightYears = 0 };
yield return new Galaxy { Name = "Andromeda", MegaLightYears = 3 };
}
}
}
public class Galaxy
{
public String Name { get; set; }
public int MegaLightYears { get; set; }
}
}
C#-Programmiersprachenspezifikation
Weitere Informationen finden Sie in der C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.