Click here to Skip to main content
14,453,469 members

The Mystery Behind ‘Yield Return’

Rate this:
4.48 (22 votes)
Please Sign up or sign in to vote.
4.48 (22 votes)
14 Jul 2009CC (ASA 2.5)
If you've ever worked with collections, then you may have come across yield return, but unless you mess around with it, you may never know that it is really a very unique way to work with your collections. This post discusses using yield return in your programs.

If you’ve been coding with .NET for a while, then you’ve most likely encountered a method that returns IEnumerable<T>. If you’re like me, you realize that this returns a list of items your can loop through and evaluate. If you ever dug into the code, you may have found a funny looking return statement yield return.

It’s basically just an array, right? We’re just returning each value as a collection to loop over, aren’t we? Well, it wouldn’t be the first time that someone, (as in myself) misunderstood the purpose of it but there really is a difference.

Let’s look at a fairly common example of returning collections.

The Usual Suspects

private string[] _Names = { "Joe", "Mary", "Bob" };

//a collection of names using a string array
public string[] GetResultsAsArray() {
    List<string> results = new List<string>();
    foreach (string name in this._Names) {
        Console.WriteLine("In GetResultsAsArray() : {0}", name);
        results.Add(name);
    }
    return results.ToArray();
}

//a collection of names using IEnumerable<string>
public IEnumerable<string> GetResultsAsEnumerable() {
    foreach (string name in this._Names) {
        Console.WriteLine("In GetResultsAsEnumerable() : {0}", name);
        yield return name;
    }
}

This is two common looking examples. The first is similar to what that joker on StackOverflow had said in the link above. The second uses yield return to return results.

So if we were to assign these values to a variable, what would our Console read?

var array = GetResultsAsArray();
var enumerable = GetResultsAsEnumerable();
Console.ReadKey();
In GetResultsAsArray() : Joe
In GetResultsAsArray() : Mary
In GetResultsAsArray() : Bob

Now, the first time I came across this, I was shocked – I know I assigned my results — what happened?

As it turns out, there is this little thing called lazy evaluation in play here – Unless we need it, the method doesn’t get called. And since we aren’t using our results anywhere, the method is never actually executed.

Lazy Yet Eager

So we’ve determined that unless we use the results of our method, the method won’t ever be executed, which on one hand is actually really quite a handy feature.

Now here is another question for you, when we do use our results — what happens then? Consider this little bit of code.

Console.WriteLine("Array -- ");
foreach (string result in GetResultsAsArray()) {
    Console.WriteLine("In the array loop : " + result);
}

Console.WriteLine("\nEnumerable -- ");
foreach (string result in GetResultsAsEnumerable()) {
    Console.WriteLine("In the enumerable loop : " + result);
}

Console.ReadKey();
Array –
In GetResultsAsArray() : Joe
In GetResultsAsArray() : Mary
In GetResultsAsArray() : Bob
In the array loop : Joe
In the array loop : Mary
In the array loop : Bob

Enumerable –
In GetResultsAsEnumerable() : Joe
In the enumerable loop : Joe
In GetResultsAsEnumerable() : Mary
In the enumerable loop : Mary
In GetResultsAsEnumerable() : Bob
In the enumerable loop : Bob

Each time yield return sent a value back to our loop, it was evaluated immediately! For being lazy code, this certainly was quick to give us our answers!

Lazy — And Maybe Late For The Party

Here’s an example where being lazy will get you into trouble, especially if you aren’t clear what it does.

IEnumerable<SearchResult> results;
using (SearchEngine search = new SearchEngine()) {
    results = search.GetEnumerableSearchResults();
}
foreach(SearchResult item in results) {
    //KABOOM!!
}

So what’s wrong with this code? I’ll tell you what – It’s that lazy, good-for-nothing call to GetEnumerableSearchResults(), that’s what!

Since our code doesn’t get evaluated until after we’ve already disposed our object, there isn’t anything there when the method is finally called! Looks like someone kicked into gear a little too late.

Of course, code like this has many practical uses, so just make sure that you use it correctly and you’ll find it to be a valuable addition to your programming toolkit.

Don’t Trust Nobody… except your Mother*

So as it turns out there really is a difference between the two, and don’t let any of those fools on StackOverflow tell you otherwise, especially when that fool is me!

*A saying my Italian grandfather used to say.

Image 1 Image 2 Image 3 Image 4 Image 5 Image 6

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution-ShareAlike 2.5 License

Share

About the Author

webdev_hb
United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pin
MVukoje28-Nov-12 23:37
MemberMVukoje28-Nov-12 23:37 
GeneralMy vote of 2 Pin
Leonardo Paneque16-May-12 6:08
MemberLeonardo Paneque16-May-12 6:08 
GeneralMy vote of 2 Pin
Erich Ledesma2-Apr-12 7:35
MemberErich Ledesma2-Apr-12 7:35 
QuestionYour logic is flawed.... Pin
mikehell6816-Mar-12 5:15
Membermikehell6816-Mar-12 5:15 
GeneralMy vote of 5 Pin
KenBonny13-Feb-12 2:44
MemberKenBonny13-Feb-12 2:44 
GeneralMy vote of 3 Pin
Leandro Taset26-Dec-11 4:58
professionalLeandro Taset26-Dec-11 4:58 
GeneralMy vote of 5 Pin
Francisco Moreno Sanz14-Oct-10 1:06
MemberFrancisco Moreno Sanz14-Oct-10 1:06 
GeneralThank you Pin
hgrewa14-Jul-09 6:34
Memberhgrewa14-Jul-09 6:34 
QuestionSo is "yield return" a shortcut for returning the next item of an iterator? Pin
supercat914-Jul-09 6:28
Membersupercat914-Jul-09 6:28 
AnswerRe: So is "yield return" a shortcut for returning the next item of an iterator? Pin
philippe dykmans20-Jul-09 8:30
Memberphilippe dykmans20-Jul-09 8:30 
GeneralRe: So is "yield return" a shortcut for returning the next item of an iterator? Pin
scott.leckie20-Jul-09 13:27
Memberscott.leckie20-Jul-09 13:27 
GeneralRe: So is "yield return" a shortcut for returning the next item of an iterator? Pin
supercat921-Jul-09 8:30
Membersupercat921-Jul-09 8:30 
GeneralRe: So is "yield return" a shortcut for returning the next item of an iterator? Pin
philippe dykmans23-Jul-09 13:56
Memberphilippe dykmans23-Jul-09 13:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 13 Jul 2009

Stats

41.7K views
37 bookmarked