Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The wonders of the yield keyword

Ok, as I was poking around with building a custom enumerator, I had noticed this behavior that concerns the yield

Say you have something like this:

  public class EnumeratorExample 
  {

        public static IEnumerable<int> GetSource(int startPoint) 
        {
                int[] values = new int[]{1,2,3,4,5,6,7};
                Contract.Invariant(startPoint < values.Length);
                bool keepSearching = true;
                int index = startPoint;

                while(keepSearching) 
                {
                      yield return values[index];
                      //The mind reels here
                      index ++ 
                      keepSearching = index < values.Length;
                }
        }

  } 

What makes it possible underneath the compiler's hood to execute the index ++ and the rest of the code in the while loop after you technically do a return from the function?

like image 819
dexter Avatar asked Dec 15 '10 22:12

dexter


People also ask

What is the yield keyword?

The yield keyword pauses generator function execution and the value of the expression following the yield keyword is returned to the generator's caller. It can be thought of as a generator-based version of the return keyword. yield can only be called directly from the generator function that contains it.

What is the purpose of yield keyword in Python?

The Yield keyword in Python is similar to a return statement used for returning values or objects in Python. However, there is a slight difference. The yield statement returns a generator object to the one who calls the function which contains yield, instead of simply returning a value.

What is the purpose of the yield statement?

In its simplest form, a yield statement looks much like a return statement, except that instead of stopping execution of the function and returning, yield instead provides a value to the code looping over the generator and pauses execution of the generator function.

What is the use of yield keyword in C#?

You use a yield return statement to return each element one at a time. The sequence returned from an iterator method can be consumed by using a foreach statement or LINQ query. Each iteration of the foreach loop calls the iterator method.


1 Answers

The compiler rewrites the code into a state machine. The single method you wrote is split up into different parts. Each time you call MoveNext (either implicity or explicitly) the state is advanced and the correct block of code is executed.

Suggested reading if you want to know more details:

  • The implementation of iterators in C# and its consequences - Raymond Chen
    • Part 1
    • Part 2
    • Part 3
  • Iterator block implementation details: auto-generated state machines - Jon Skeet
  • Eric Lippert's blog
like image 136
Mark Byers Avatar answered Oct 06 '22 08:10

Mark Byers