2

How Yield works within a foreach loop shown below? lstNumbers is of type List<int>.

foreach (int i in lstNumbers)
{
    yield return i;
}

Will it start returning as it receives the value or it returns the final list at the end?

How is it different from:

   foreach (int i in lstNumbers)
    {
        return i;
    }
RKh
  • 13,818
  • 46
  • 152
  • 265
  • maybe you should just read this http://msdn.microsoft.com/en-us/library/vstudio/9k7k7cf0.aspx – Marius Bancila Feb 17 '13 at 16:59
  • you get the next value for i from the list for every iteration – Amitd Feb 17 '13 at 17:01
  • I'm a bit confused on how return works. It is obvious from the second code that it will exit the loop after the first value is returned. But why the loop with Yield is not exited. – RKh Feb 17 '13 at 17:05
  • 1
    the way yield is implemented it creates a state machine behind the scenes to preserve the values for the loop. – Amitd Feb 17 '13 at 17:08
  • 1
    See http://stackoverflow.com/questions/742497/yield-statement-implementation for details. – Matthew Watson Feb 17 '13 at 17:38

2 Answers2

1

In this example it will return all the values, one by one, but the consuming code needs to start iterating over the resultset:

foreach (int i in lstNumbers)
{
    yield return i;
}

Take a look at the following example which will print 1, 2 on the console and the for loop inside the method will never reach an end if the consuming code doesn't iterate over the enumerable:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        foreach (var item in Get().Take(2))
        {
            Console.WriteLine(item);
        }
    }

    static IEnumerable<int> Get()
    {
        foreach (var item in new[] { 1, 2, 3 })
        {
            yield return item;
        }
    }
}

You probably don't need to be yielding anything in this case but simply return the result because you already have it:

return lstNumbers;

whereas in the second case:

foreach (int i in lstNumbers)
{
    return i;
}

you are simply returning the first value of the list and the iteration breaks immediately.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Actually I am trying to understand how the values are returned. In the first code, are they returned one by one or as a resultset? – RKh Feb 17 '13 at 17:02
  • They are returned one by one. When the calling code starts to enumerate over the result of the function and advances the enumerator. If the calling code stops the enumeration the `for` loop inside your method might never reach an end. I have updated my answer to show an example. – Darin Dimitrov Feb 17 '13 at 17:03
0

In first case it just returns i in the moment of call to return i.

After the caller calls an iterator over the function again it will jump to the next iteration.

Example to make it clear:

int GetNextNumber() {
  foreach (int in in lstNumbers)
  {
     yield return in;  //returns on first hit
  }
}

and after

foreach(var i in GetNextNumber()) {
     //process number got from the GetNextNumber()
     //on next iteration GetNextNumber() will be called again 
     // so the next number from lstNumbers will be returned
}

It's a very common way to dealing with long data streams, where you sequentially pick on piece of it process and after request another, and so on..

In second case, instead, you will just always return the first element in the list, and never jump to others.

Tigran
  • 61,654
  • 8
  • 86
  • 123