Skip to content

Yield return

Anand Patel edited this page Nov 27, 2016 · 12 revisions

Yield return versus traditional loops

Let’s have a look at a different example. We’ll start with a traditional loop which returns a list:

IEnumerable<int> GenerateWithoutYield()
{
    var i = 0;
    var list = new List<int>();
    while (i<5)
        list.Add(++i);
    return list;
}

foreach(var number in GenerateWithoutYield()) 
    Console.WriteLine(number);

These are the steps that are executed:

  1. GenerateWithoutYield is called.
  2. The entire method gets executed and the list is constructed.
  3. The foreach-construct loops over all the values in the list.
  4. The net result is that we get numbers 1 to 5 printed in the console.

Now, let’s look at an example with the yield return statement:

IEnumerable<int> GenerateWithYield()
{
    var i = 0;
    while (i<5)
        yield return ++i;
}

foreach(var number in GenerateWithYield())
    Console.WriteLine(number);

At first sight, we might think that this is a function which returns a list of 5 numbers. However, because of the yield-statement, this is actually something completely different. This method doesn’t in fact return a list at all. What it does is it creates a state-machine with a promise to return 5 numbers. That’s a whole different thing than a list of 5 numbers. While often the result is the same, there are certain subtleties you need to be aware of.

This is what happens when we execute this code:

  1. GenerateWithYield is called.
  2. This returns an IEnumerable. Remember that it’s not returning a list, but a promise to return a sequence of numbers when asked for it (more concretely, it exposes an iterator to allow us to act on that promise).
  3. Each iteration of the foreach loop calls the iterator method. When the yield return statement is reached the value is returned, and the current location in code is retained. Execution is restarted from that location the next time that the iterator function is called.
  4. The end result is that you get the numbers 1 to 5 printed in the console.

References

Clone this wiki locally