yield return ist wie du festgesellt hast "Syntactic Sugar" und erlaubt es auf einfache weise Iterationen zu implementieren.
Du kannst dir mal mit dem Reflektor anschauen wie viel Code der Compiler aus dem yield generiert. Dabei wirst du feststellen dass es eine gute Idee war yield in die Sprache einzuführen.
Die Anwendungszwecke haben sich seit Einführung von LINQ verringert denn seither sind Iterationen nicht mehr so oft explizit zu programmieren. LINQ verwendet jedoch intern yield sehr häufig (eigentlich immer) - ist im Reflektor aber nicht sichtbar denn der Compiler hat dafür ja Code generiert.
Ein konkreter Anwendungsfall für yield ist wenn eine eigene Methode als Rückgabewert IEnumerable<T> haben soll.
public IEnumerable<string> ReadLines(string fileName) { using (StreamReader sr = new StreamReader(fileName)) { while (!sr.EndOfStream) yield return sr.ReadLine(); } }
Welchen Vorteil hat es effektiv im vergleich zu "var lines = new List<String>()"? 2 mehr/weniger im Vergleich zu deinem Beispiel wird doch nicht die Ursache sein?
1) Dein Snippet erfüllt nicht dem was mein Beispiel zeigt - es ist nur eine Deklaration und somit kann ich den Vorteil/Nachteil nicht bewerten da es nicht vergleichbar ist ;)
2) In meinem Beispiel werden aus einer Datei die Zeilen gelesen. Diese werden nicht alle auf einmal in den RAM gelesen sondern zeilenweise. Stell dir eine Datei mit 1e6 Zeilen vor (oder sonst etwas was nicht in den RAM passt). Da kommst du um so etwas nicht rum.
Ein wirklich sinnvoller Anwendungszweck für yield ist dann gegeben, wenn du nicht nur einen Zustand eines Aufrufs behalten willst, sondern einen ganzen Aufrufstack. Willst du beispielsweise alle Knoten eines Binärbaumes In-Order Ausgeben, dann geht das mit
public IEnumerable<string> readInOrder() { foreach(string s in leftChild.readInOrder()) yield return s; yield return myValue; foreach(string s in rightChild.readInOrder()) yield return s; }
(Mit der Warnung von Donald E. Knuth: Beware of bugs in the above code; I have only proved it correct, not tried it.)
Dem stimme ich zu. Der Jammer ist eigentlich mehr, dass C# nicht allgemein Koroutinen bekommen hat, sondern nur ein (Einbahnstraßen-)yield für den speziellen Anwendungszweck, die Programmierung von Iteratoren zu vereinfachen.