yield return - Schlüsselwort für verzögerte Ausführung (2024)

Wenn du eine eigene Methode zum Iterieren von Auflistungen (das muss nicht unbedingt eine Collection sein) schreibst, dann kann dir yield return Arbeit abnehmen. Dabei musst du dich entscheiden, ob du alle Elemente auf einmal bearbeitest (eager evaluation), oder ob du ein Element immer nur dann bearbeitest, wenn es gerade gebraucht wird (lazy evaluation).

Sofortige Ausführung

Wenn du eine Methode wie zum Beispiel int Quadriere(int wert) hast, und diese auf eine ganze Reihe von Werten anwenden möchtest, kannst du das so machen:

IEnumerable<int> ZahlenreiheQuadrieren(int maxIndex){ var result = new int[maxIndex]; for(int i = 0; i < maxIndex; i++) { result[i] = Quadriere(i); } return result;}

Es gibt wesentlich elegantere Möglichkeiten, aber mit dieser Lösung kommst du zum Ziel. Rufst du diese Methode wie folgt auf, dann wird das neue Feld sofort angelegt, mit den entsprechenden Zahlen gefüllt und du hast direkten Zugriff darauf:

Verzögerte, aber eifrige Ausführung

Eine ähnliche Lösung kannst du auch mit yield return erzeugen:

IEnumerable<int> ZahlenreiheQuadrieren(int maxIndex){ var result = new int[maxIndex]; for(int i = 0; i < maxIndex; i++) { result[i] = Quadriere(i); } foreach(var value in result) { yield return value; }}

Rufst du diese Variante auf, ist der Ablauf anders. Denn das Aufrufen, also IEnumerable<int> quadrierteZahlen = ZahlenreiheQuadrieren(5); erzeugt nun nicht mehr sofort das Feld und macht alle Berechnungen, sondern es wird lediglich ein Objekt angelegt und quadrierteZahlen zugewiesen. Dieses Objekt weiß, dass bei jedem Zugriff auf quadrierteZahlen der definiert Methodenrumpf ausgeführt werden muss und speichert für maxIndex den Wert 5.

Erst wenn du das erstmal auf quadrierteZahlen zugreifst (z.B. erste Iteration von foreach(var quadratZahl in quadrierteZahlen) ...), wird das entsprechende Feld angelegt, alle Zahlen berechnet und schließlich die erste berechnete Zahl zurückgegeben. Durch die Verwendung von yield return gibt es also eine verzögerte Ausführung des Methodenrumpfes. Eager evaluation bedeutet hier, dass bei der ersten Iteration alles bearbeitet wird und in den folge Iterationen nur noch das jeweilige Element zurückgegeben wird.

Verzögerte und träge Ausführung

Du kannst das ganze aber auch noch weiter verzögern:

IEnumerable<int> ZahlenreiheQuadrieren(int maxIndex){ for(int i = 0; i < maxIndex; i++) { yield return Quadriere(i); }}

Bei dieser Variante wird die Berechnung tatsächlich erst in jeder Iteration von foreach(var quadratZahl in quadrierteZahlen) ... ausgeführt. Es gibt also keinen initialen Aufwand um das Feld anzulegen und alle Elemente darin zu berechnen, sondern der Aufwand ist gleichmäßig über die Iterationen der foreach Schleife verteilt.

Nicht jedes IEnumerable verhält sich gleich

Wenn du dir die 3 Varianten anschaust, gibt es einen wesentlichen Unterschied. Bei der sofortigen Ausführung, bekommst du einen Iterator, der dir direkten Zugriff auf die Auflistung ermöglicht. So kannst du mit dem Iterator Werte direkt in der Auflistung verändern (sofern der Typ der Auflistung dies erlaubt) und siehst bei weiterer Verwendung der gleichen Iterator-Instanz die Änderungen. Im Beispiel oben, referenziert der Iterator das temporäre Feld und bewahrt es so vor dem Garbage Collector.

Bei der verzögerten Ausführung, egal ob eifrig oder träge, ist das anders. Sie bewirkt, dass im Moment des Zugriffs auf ein Element der Auflistung mit dem Iterator, dieses Element erst erzeugt wird. Sofern dieses Element nicht explizit referenziert wird, ist es sofort für den Garbage Collector freigegeben. Nur mit dem Iterator kannst du also die Auflistung nicht ändern. Entsprechende Beispiele findest du im Quelltext zu diesem LernMoment.

Jetzt erstmal viel Spaß mit beim eifrigen oder trägen Zugriff

Jan

Merke

  • Ein IEnumerable<T> verhält sich bei sofortiger Ausführung wesentlich anders als bei verzögerter Ausführung.
  • Erstellst du eine Iterator-Methode mit yield return, handelt es sich um verzögerte Ausführung.
  • Bearbeitest du alle Elemente einer Auflistung (z.B. beim Sortieren) und gibst sie dann mit yield return zurück, heißt das eifrige Ausführung bzw. eager evaluation.
  • Bearbeitest du immer genau ein Element beim Zugriff auf den Iterator, wird das träge Ausführung bzw. lazy evaluation genannt.

Lernquiz

Verwende folgende Fragen, um das Gelernte von heute zu festigen:

  • Was ist der Unterschied zwischen sofortiger Ausführung und verzögerter Ausführung?
  • Wie erstellst du eine “eifrige” Iterator-Methode?
  • Wie erstellst du eine “träge” Iterator-Methode?

Am besten schaust du dir morgen und dann nochmal in ein paar Tagen die vorherigen Fragen an und beantwortest sie, ohne den Text vorher gelesen zu haben.

Weitere Informationen

  • Den kompletten Quelltext zum heutigen Lernmoment findest du hier.
  • Insbesondere die Problematik mit Änderung von Werten bei verzögerter Ausführung ist in diesem Artikel beschrieben.
  • Die Einführung in das Thema von Microsoft ist auf MSDN zu finden.
  • Eine unglaublich präzise Erklärung gibt es in dieser Antwort auf StackOverflow.

Dieser LernMoment hat dir gefallen?
Dann melde dich an und du wirst über neue LernMomente informiert:
yield return - Schlüsselwort für verzögerte Ausführung (2024)

FAQs

What does yield return mean? ›

Yield is the amount an investment earns during a time period, usually reflected as a percentage. Return is how much an investment earns or loses over time, reflected as the difference in the holding's dollar value. The yield is forward-looking and the return is backward-looking.

What is the difference between yield break and yield return? ›

The yield keyword is used in two forms: yield return - returns an expression at each iteration. yield break - terminates the iteration.

When would you use the yield break statement? ›

You can use the yield break statement to stop iteration and exit the iterator block.

What is the difference between yield break and yield return null in unity? ›

"yield break" breaks the Coroutine (it's similar as "return"). "yield return null" means that Unity will wait the next frame to finish the current scope. "yield return new" is similar to "yield return null" but this is used to call another coroutine. Code (CSharp):

Which is better yield or return? ›

If you are relying on your investments to provide consistent income, the dividend yield is more important. If you have a long-term investment horizon and plan on holding a portfolio for a long time, it makes more sense to focus on total return.

Is high yield good or bad? ›

High-yield, or "junk" bonds are those debt securities issued by companies with less certain prospects and a greater probability of default. These bonds are inherently more risky than bonds issued by more credit-worthy companies, but with greater risk also comes greater potential for return.

Why use yield instead of return? ›

In conclusion, yield and return are both powerful features in Python that serve different purposes. The yield statement is used to create generator functions that can produce a series of values lazily, while the return statement is used to exit a function and return a single value.

What should the return type be for a method that uses yield return? ›

IEnumerable is the return type from an iterator. An iterator is a method that uses the yield return keywords. yield return is different from a normal return statement because, while it does return a value from the function, it doesn't “close the book” on that function.

Is it good to use break statements? ›

There's nothing wrong with the break or continue statements or even the dreaded goto statement. They're just ways to control the flow of computer programs. When programming, it's important to write the code so that it's easy to follow the logic of the program.

Is yield faster than return? ›

In fact, it stores all the returned values inside this generator object in a local state. If you have used the return statement, which returned an array of values, this would have consumed a lot of memory. Hence, yield should always be preferred over the return in such cases.

Why is yield return null? ›

yield return null will wait until the next frame and then continue execution. In your case it will check the condition of your while loop the next frame. The "why this is necessary" is probably because you want the object to move by an input every frame.

What is the difference between yield return 0 and yield return null? ›

The biggest difference is that yield return 0 allocates memory because of boxing and unboxing of the 0 that happens under the hood, but yield return null does not allocate memory. Because of this, it is highly recommended to use yield return null if you care about performance.

Is yield better than dividends? ›

Dividend Growth is the Winning Strategy

While Dividend Yield provides a useful snapshot of a stock's immediate income potential, Yield on Cost offers a deeper understanding of the long-term growth in income.

Is a 20% yield good? ›

Think of percent yield as a grade for the experiment: 90 is great, 70-80 good, 40-70 fair, 20-40 poor, 0-20 very poor. (Please realize that the above definitions of what constitutes good, fair, poor, etc. yields are arbitrary and that other factors play a role.

Is a 2% yield good? ›

Yields from 2% to 6% are generally considered to be a good dividend yield, but there are plenty of factors to consider when deciding if a stock's yield makes it a good investment.

What is a good yield amount? ›

All in all, though, a good yield is anywhere between 5 and 8%, but you should aim for 7 to 8% or beyond for the best yield on property investment. So when you're wondering what is a good rental yield for your property, aim for somewhere between these numbers.

References

Top Articles
Latest Posts
Article information

Author: Reed Wilderman

Last Updated:

Views: 5808

Rating: 4.1 / 5 (52 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Reed Wilderman

Birthday: 1992-06-14

Address: 998 Estell Village, Lake Oscarberg, SD 48713-6877

Phone: +21813267449721

Job: Technology Engineer

Hobby: Swimming, Do it yourself, Beekeeping, Lapidary, Cosplaying, Hiking, Graffiti

Introduction: My name is Reed Wilderman, I am a faithful, bright, lucky, adventurous, lively, rich, vast person who loves writing and wants to share my knowledge and understanding with you.