Thought for the Dazed

I've had to give up that Distance Learning course as I was having trouble seeing the teacher.

Flickr
www.flickr.com
RobMiles' items Go to RobMiles' photostream
Twitter
C# Yellow Book

Search entire site
« Last Friday Tutorial of the Year | Main | The Rob Miles Roadshow »
Friday
Apr082011

C# Yield Return Fun

public static IEnumerable YieldFun()
{
    yield return 1;
    yield return 2;
    yield return 3;
}

static void Main(string[] args)
{
    foreach (int i in YieldFun())
    {
        Console.WriteLine(i);
    }
}

If you can tell me what the code above does, you understand how yield return works. If you can’t, read on……

In a C# program you can mark things as implementing the IEnumerable interface (to use this you need to have a using System.Collections; at the top of your program). This means the thing can be enumerated,  i.e. it means that I can get a succession of objects from it.

The best way to work through something that can be enumerated is by using the foreach construction, as shown above. You’ve probably seen foreach when you’ve worked through items in a collection such as a List or an array.  In the above code we are using foreach to work through the enumerable results that the YieldFun method returns. 

The code inside YieldFun looks a bit scary. The yield return keyword combination is followed by the thing that you want to send back for this iteration. In this case I’m just returning a different number each time. What happens when the yield return is reached is that the method stops at that point, returns the result and then, when the foreach asks for the next value, the method wakes up and continues at the next statement. The result of the program is simply the sequence:

1
2
3

If you want to programmatically supply a sequence of items to a consumer then this is  a great way to do it. 

Reader Comments (7)

what happens when the last yield statement is reached? does it roll around back to the first value, or generate an error?
April 8, 2011 | Unregistered Commenterdan
When the enumerating method ends the foreach loop stops. This means that it drops out of the loop and the program above ends.
April 8, 2011 | Registered CommenterRob
You might want to read this article...
http://msdn.microsoft.com/en-us/magazine/cc163682.aspx

It states iterators and yield in much more detail.
April 11, 2011 | Unregistered CommenterBart Czernicki
haha. i meant what happens if i were to call the method in the above program a fourth time? would it fall over and say the method has been called too many times, or would it roll back around and return 1?
April 13, 2011 | Unregistered Commenterdan
dan, how can you call the method a fourth time in foreach loop?
April 19, 2011 | Unregistered CommenterMike
As soon as the first yield statement is encountered, the execution-state (execution sequence or stack pointers or whatever it may be) of the YieldFun() method must be retained some where and the control is sent back to foreach() loop with return value (1)
The foreach loop consumes the returned value and sends the control back to the NEXT STATEMENT (remember I said the execution-state is retained ) in the YieldFun() method which is again a yield statement (yield return 2), so 2 is returned to foreach() and it consumes 2

When the foreach() loop send the control back to YieldFun() after consuming 3, there are no more yield return statements but } --indicating end of YieldFun() method and control returns to foreach() without any value indicating it's over.

BOTTOMLINE - The idea is to make only one value available per iteration to the foreach() loop
instead of Creating and returning the whole big collection at once.
September 17, 2012 | Unregistered CommenterSaurabh
Hey Rob, I think that's the clearest most concise explanation of yield that I've seen -- thank you!
December 6, 2012 | Unregistered CommenterMercator

PostPost a New Comment

Enter your information below to add a new comment.
Author Email (optional):
Author URL (optional):
Post:
 
All HTML will be escaped. Hyperlinks will be created for URLs automatically.