| 

.NET C# Java Javascript Exception

2
Was ist da anders als bei dem normalen return?
04.03.2011
Adorkable 21 2
3 Antworten
1
Yield funktioniert nur mit den Rückgabewerten IEnumerable<Type> und IEnumerable.
Eine schöne Beschreibung und Beispiele findest du bei donetperls und natürlich in der MSDN.
04.03.2011
Jürgen Luhr 7,1k 2 9
1
yield kann verwendet werden in Methoden mit den beiden Rückgabetypen, die Jürgen genannt hat, sowie in solchen mit Rückgabetyp IEnumerator oder IEnumerator<T>. Es ist ein sehr mächtiges Feature des C#-Compilers, das es erlaubt, auf einfache und elegante Weise eines dieser 4 Interfaces zu implementieren. Du kannst in einer Methode nicht eines der beiden yield-Konstrukte (yield return und/oder yield break) und das "einfache" return verwenden.

Der Method-Body, den Du selbst programmierst, wird vom Compiler als Kern eines generierten Code-Segments hergenommen, das die IEnumerator (bzw. IEnumerable-)Schnittstelle implementiert. Beim Aufruf der Methode wird Dein Code gar nicht betreten, sie kehrt scheinbar sofort zurück (tatsächlich wird ein Teil des generierten Codes ausgeführt). Beim ersten MoveNext() (das der Aufrufer i.d.R. implizit durch Eintritt in eine foreach-Schleife auslöst) wird der Method-Body bis zum ersten yield ausgeführt. Ist es ein yield return, ist der zurückgegebene Wert derjenige, der als Current auf dem Enumerator zur Verfügung steht (und damit als aktueller Wert in der foreach-Schleife des Aufrufers). Ist es hingegen ein yield break, ist der Enumerator zu Ende. Der generierte Code merkt sich, an welcher Stelle die Ausführung war, und setzt beim nächsten MoveNext an der Stelle fort, bis zum nächsten yield. Am besten mal schrittweise debuggen, Code-Beispiele findest Du ja an den von Jürgen angegebenen Stellen.

Der Witz ist: ich kann damit sehr einfach eine Methode programmieren, die eine Auflistung zurückgibt, ohne diese Auflistung als ganzes instanziieren zu müssen. Besonders interessant ist das, wenn meine Eingabe selbst eine Auflistung ist. Wenn ich z.B. aus einer Auflistung von Strings eine Auflistung derjenigen Strings filtern will, die mehr als 10 Zeichen haben, kann ich das mit einer yield-Konstruktion so lösen, dass der Code zum einen auch dann noch funktioniert, wenn die Eingabe ein Enumerator über meinen kompletten Festplatteninhalt ist, und zum anderen auch so effizient, dass nur soviel aus der Eingabe gelesen wird, wie für den Aufrufer benötigt wird - der sich vielleicht entscheidet, schon nach 3 Iterationen abzubrechen, auch wenn das Ergebnis 3000 Einträge hätte.

In der dotnetpro gab es in Golo Rodens Reihe "Scharfes C" mal einen Beitrag dazu, wenn ich mich richtig erinnere. Und in der aktuellen Ausgabe ist ein Artikel von Ralf Westphal zum Einsatz von IEnumerable<T>, der auch den Nutzen von yield nochmal verdeutlicht.
04.03.2011
Matthias Hlawatsch 13,2k 4 9
0
AFAIK unterbricht yield die Ausführung nur, kann sie aber später an der gleichen Stelle fortsetzen. Dies ist besonders bei Coroutinen interessant, die sich wechselseitig gegeneinander aufrufen.
04.03.2011
theorist 494 6

Stelle deine Return-Frage jetzt!