Give way to the yield keyword!

Yield! I ran into this keyword by accident (yield, accident... very funny), and I must say - this accident was a good one!
yield is a small keyword who has gotten used to live by the shadows of the celebrity keywords (static, const, Paris Hilton, Madonna, etc.), and I say – let's change it! Let's give yield what it deserves!

 

Why am I so thrilled about it?
OK, so let's introduce yield first – yield comes to help us to create an enumerator out of a single method.
For example, this code:

public static IEnumerable YieldTest(int num)

{

  for (int i = 0; i < num; i++)

  {

    yield return i;

  }

  yield break;

}     

 

static void Main(string[] args)

{

    foreach (int num in YieldTest(8))

    {

        Console.WriteLine(num);

    }

}

Will result in:

0
1
2
3
4
5
6
7
Press any key to continue . . .

As you could see, yield has 2 possible continuations – return and break:
yield return <something> means that <something> is going to be the next enumerator value.
yield break means that the party is over and so is our enumeration…

This means that yield return does not act as a regular return keyword - it doesn't really end the method's execution. yield return pauses the method execution and the next time you call it (for the next enumeration value), the method will continue to execute from the last yield return call. It sounds a bit confusing I think... Think of it that way - IEnumerator.MoveNext() really moves forward in the method till the next yield return\break statement.

Still asking yourself why am I so thrilled about my new precious keyword?
Well, this is a code saver! and I like code savers!

I can see it saves me code lines on 2 occasions:

1. When developing my very own enumerable object. See the difference in the next 2 samples:
A regular implementation (2 classes, 44 lines):

public class Users :IEnumerable

{

    // --- IEnumerable Members ---

 

    public IEnumerator GetEnumerator()

    {

        return new UserEnumerator(10);

    }

}

 

public class UserEnumerator : IEnumerator

{       

    private int m_index;

    private int m_maxIndex;

 

    private string GetUserName(int index)

    {

        return "User #" + index.ToString();

    }       

 

    public UserEnumerator(int maxIndex)

    {

        m_maxIndex = maxIndex;

        Reset();

    }       

 

    // --- IEnumerator Members ---

 

    public object Current

    {

        get { return GetUserName(m_index); }

    }

 

    public bool MoveNext()

    {

        m_index++;

        return (m_index < m_maxIndex);

    }

 

    public void Reset()

    {

        m_index = -1;

    }       

}

A yield implementation (1 class, 19 lines):

public class UsersYield :IEnumerable

{

    private string GetUserName(int index)

    {

        return "User #" + index.ToString();

    }   

 

    // --- IEnumerable Members ---

 

    public IEnumerator GetEnumerator()

    {

        for (int i = 0; i < 10; i++)

        {

            yield return GetUserName(i);

        }

 

        yield break;

    }

}

2. When developing a method that returns a list and I know that all I'm gonna do is loop over it. Here, the amount of code it saves is not as big as the in the previous bullet, but the code makes more sense, which is even better! For example:

private IEnumerable GetDaysOfWeek()

{

    yield return "Sunday";

    yield return "Monday";

    yield return "Tuesday";

    yield return "Wednesday";

    yield return "Thursday";

    yield return "Friday";

    yield return "Saturday";

    yield break;

}

 

public void LoopOverDaysOfWeek()

{

    foreach (string day in GetDaysOfWeek())

    {

        // do something               

    }

}

Did you notice in the last 2 sample codes that yield can return IEnumerator and IEnumerable? The fun just never stops!

So the yield keyword is indeed very helpful BUT, and it's a big but as you can see, be careful with it!
For instance, one can go and write the following code:

public IEnumerable BadYieldUsage()

{

    int i = 100;

    while (i > 0)

    {

        if (i % 2 == 0)

        {           

            if (i > 12)

            {

                yield return "Even";

            }

            else

            {

                yield break;

            }

        }

        else

        {

            yield return "Odd";

        }

        i--;

    }

}

I want to promise you – if you write a similar code block and actually use it, the end of the world, without any doubt, will come.
Keep the enumeration code as simple as you can because debugging it afterwards will turn you into a suicidal human being.

In conclusion, the yield keyword on the one hand, will save you lines of code, make it more readable in some cases and eventually make you happier. On the other hand, overusing it might kill you.

Fun fun fun!

Have fun!
Shay.

Share this post :

Comments

# Give way to the yield keyword!

Friday, June 06, 2008 4:48 PM by DotNetKicks.com

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# RE:yield

Friday, June 06, 2008 8:36 PM by life = code + sleep

Replying to this post about the use of yield , here is an everyday practical example: split a string

# re: Give way to the yield keyword!

Saturday, June 07, 2008 9:10 PM by Mark Hildreth

In the simplest of cases (which is typically where I'm using yield), you don't even need the yield break at the end. When the method returns, it's assumed that the enumeration is complete. I used the yield keyword for awhile before I even realized that there was a yield break :P

# Dew Drop &ndash; June 7, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop &ndash; June 7, 2008 | Alvin Ashcraft's Morning Dew

# re: Give way to the yield keyword!

Sunday, June 08, 2008 8:48 PM by James Lanng

There's a way to avoid surprises like this... reading the language spec isn't as boring as you might imagine.

BTW, debugging the yield keyword isn't too hard in my experience.

# The Tomes Of Experience &raquo; C# Yeild Keyword

Monday, June 09, 2008 6:50 AM by The Tomes Of Experience » C# Yeild Keyword

Pingback from  The Tomes Of Experience    &raquo; C# Yeild Keyword

# Delayed execution and

Monday, June 09, 2008 2:39 PM by CodeThinked

Delayed execution and

# Arjan`s World &raquo; LINKBLOG for June 9, 2008

Monday, June 09, 2008 5:24 PM by Arjan`s World » LINKBLOG for June 9, 2008

Pingback from  Arjan`s World    &raquo; LINKBLOG for June 9, 2008

# W&ouml;chentliche Rundablage: Silverlight 2, WPF, ASP.NET MVC, jQuery&#8230; | Code-Inside Blog

Pingback from  W&ouml;chentliche Rundablage: Silverlight 2, WPF, ASP.NET MVC, jQuery&#8230; | Code-Inside Blog

# Weekly Links: Silverlight 2, WPF, ASP.NET MVC, jQuery&#8230; | Code-Inside Blog International

Pingback from  Weekly Links: Silverlight 2, WPF, ASP.NET MVC, jQuery&#8230; | Code-Inside Blog International

# re: Give way to the yield keyword!

Tuesday, June 10, 2008 12:38 AM by Lars Corneliussen

Great posting!!

I explained how the yield statement works behind the scenes of the C# compiler.

startbigthinksmall.wordpress.com/.../behind-the-scenes-of-the-c-yield-keyword

# Behind the scenes of the C# yield keyword &laquo; .Net Braindrops

Pingback from  Behind the scenes of the C# yield keyword &laquo; .Net Braindrops

# yield "I love CSharp"

Wednesday, June 11, 2008 4:28 PM by NullReferenceException

yield "I love CSharp"

# Code Heaven's Required Reading - June 22, 2008

Monday, June 23, 2008 4:50 AM by Code Heaven

It&#39;s that time for more blatant link whoring. Software is hard! (from YTechie). To this day, it floors

# re: Give way to the yield keyword!

Wednesday, January 07, 2009 12:30 AM by alphatester

what is wrong with BadYieldUsage method? I tried it and does the job.

# re: Give way to the yield keyword!

Wednesday, January 07, 2009 9:38 AM by shayf

@alphatester - the BadYieldUsage method works great, I only gave it as an example of implementations you should avoid because it will be pretty annoying to debug.

# C# tips &laquo; Bobobobo&#8217;s Weblog

Saturday, January 24, 2009 6:05 PM by C# tips « Bobobobo’s Weblog

Pingback from  C# tips &laquo; Bobobobo&#8217;s Weblog

# port and cat &raquo; C# tips

Friday, March 06, 2009 5:09 AM by port and cat » C# tips

Pingback from  port and cat  &raquo; C# tips

# re: Give way to the yield keyword!

Friday, September 25, 2009 3:56 PM by The Guy Who Laughed!

Man, People funny like you explains it better! :)

Thanks for sharing!

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: