Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need help understanding C# yield in IEnumerable

Tags:

c#

i am reading C# 2010 Accelerated. i dont get what is yield

When GetEnumerator is called, the code in the method that contains the yield statement is not actually executed at that point in time. Instead, the compiler generates an enumerator class, and that class contains the yield block code

public IEnumerator<T> GetEnumerator() { 
    foreach( T item in items ) { 
        yield return item; 
    } 
} 

i also read from Some help understanding “yield”

yield is a lazy producer of data, only producing another item after the first has been retrieved, whereas returning a list will return everything in one go.

does this mean that each call to GetEnumerator will get 1 item from the collection? so 1st call i get 1st item, 2nd, i get the 2nd and so on ... ?

like image 928
Jiew Meng Avatar asked Aug 11 '10 12:08

Jiew Meng


People also ask

Is C easy to understand?

While C is one of the more difficult languages to learn, it's still an excellent first language pick up because almost all programming languages are implemented in it. This means that once you learn C, it'll be simple to learn more languages like C++ and C#.

Is C language hard for beginners?

C is more difficult to learn than JavaScript, but it's a valuable skill to have because most programming languages are actually implemented in C. This is because C is a “machine-level” language. So learning it will teach you how a computer works and will actually make learning new languages in the future easier.


3 Answers

Best way to think of it is when you first request an item from an IEnumerator (for example in a foreach), it starts running trough the method, and when it hits a yield return it pauses execution and returns that item for you to use in your foreach. Then you request the next item, it resumes the code where it left and repeats the cycle until it encounters either yield break or the end of the method.

public IEnumerator<string> enumerateSomeStrings()
{
    yield return "one";
    yield return "two";
    var array = new[] { "three", "four" }
    foreach (var item in array)
        yield return item;
    yield return "five";
}
like image 161
manixrock Avatar answered Sep 28 '22 03:09

manixrock


Take a look at the IEnumerator<T> interface; that may well to clarify what's happening. The compiler takes your code and turns it into a class that implements both IEnumerable<T> and IEnumerator<T>. The call to GetEnumerator() simply returns the class itself.

The implementation is basically a state machine, which, for each call to MoveNext(), executes the code up until the next yield return and then sets Current to the return value. The foreach loop uses this enumerator to walk through the enumerated items, calling MoveNext() before each iteration of the loop. The compiler is really doing some very cool things here, making yield return one of the most powerful constructs in the language. From the programmer's perspective, it's just an easy way to lazily return items upon request.

like image 36
Dan Bryant Avatar answered Sep 28 '22 02:09

Dan Bryant


Yes thats right, heres the example from MSDN that illustrates how to use it

public class List
{
    //using System.Collections;
    public static IEnumerable Power(int number, int exponent)
    {
        int counter = 0;
        int result = 1;
        while (counter++ < exponent)
        {
            result = result * number;
            yield return result;
        }
    }

    static void Main()
    {
        // Display powers of 2 up to the exponent 8:
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }
}
/*
Output:
2 4 8 16 32 64 128 256 
*/
like image 25
Iain Ward Avatar answered Sep 28 '22 02:09

Iain Ward