2

First, of all, I already search about this but i still can't I understand when to use yield.

For example I have the below code:

string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

public System.Collections.IEnumerator GetEnumerator()
{
    for (int i = 0; i < days.Length; i++)
    {
        yield return days[i];
    }
}

What would be the difference between the above code and below code?

string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };

public System.Collections.IEnumerator GetEnumerator()
{
    for (int i = 0; i < days.Length; i++)
    {
        return days[i];
    }
}

Can you please tell me when to use yield?

Pinoy2015
  • 1,429
  • 15
  • 29
  • 2
    possible duplicate of [What is yield return in C#?](http://stackoverflow.com/questions/1407162/what-is-yield-return-in-c) – Evan Mulawski Jun 15 '12 at 00:42
  • which is a possible duplicate of [What is the yield keyword used for in C#?](http://stackoverflow.com/questions/39476/what-is-the-yield-keyword-used-for-in-c) :) – Steve Konves Jun 15 '12 at 00:47

3 Answers3

10

The return method doesn't remember where you are in your array. It will return Sunday every single time you use it, simply because it starts that loop from zero every time.

Using yield is more (at least conceptually) "I'll return this value but, next time you call me, I'm going to pick up where I left off (inside the loop)".

A similar thing can be done in C with the use of static variables to remember where you are:

char *nextDay () {
    static char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" };
    static int nextDay = -1;
    nextDay = (nextDay + 1) % (sizeof (days) / sizeof (*days));
    return days[nextDay];
}

The fact that the nextDay variable is maintained across invocations of the function means that it can be used to cycle through the array.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Hi in the code below string[] days = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; public System.Collections.IEnumerator GetEnumerator() { for (int i = 0; i < days.Length; i++) { yield return days[i]; } } When I first call it, it will return "sun", and in second time it will return "Mon"? Did I understand it correctly? – Pinoy2015 Jun 15 '12 at 01:01
  • @pagodnautak, yes, any bugs notwithstanding (it's a little hard to read code in the comments box), that is the expected functionality. – paxdiablo Jun 15 '12 at 01:12
4

Certain constructs in C# will cause the compiler to turn the code into something very different. The yield return statement causes such a transformation. What looks like a function which performs a yield return is actually compiled into a class; many of the local variables in the function get transformed into class fields. The class itself will typically implement IEnumerable<T> and IEnumerator<T>. The first time MoveNext is called, the class code will run the portion of the function up to the first yield return, and keep track of which yield return it hit. The next time it's called, it will start execution there and run until the next yield return is called. If there are any Try/Finally blocks, the portion of the code in the Finally block will get executed in response to IDisposable.Dispose.

The net effect is that the code the C# compiler produces for an iterator will look almost nothing like the code the programmer wrote. The reason it seems like yield return does the impossible is that its behavior would be impossible for anything even remotely resembling a method call, but the compiler turns any function which contains a yield return into a class whose behavior doesn't even remotely resemble a method call.

supercat
  • 77,689
  • 9
  • 166
  • 211
0

Yield interacts with foreach-loops and for loops. It allows each iteration in a foreach-loop or for loop be generated only when needed. In this way it can improve performance.

Complete explaination of yield and its benefits can be found here:

http://www.ytechie.com/2009/02/using-c-yield-for-readability-and-performance.html

Jason De Oliveira
  • 1,732
  • 9
  • 16
  • It would be more accurate to say `yield` interacts with consumers of `IEnumerable`, of which, a `foreach` loop is but a common example. Yield also works perfectly fine if you invoke `.GetEnumerator` yourself and traverse it manually. – Kirk Woll Jun 15 '12 at 01:16