Wednesday, August 24, 2011

C# Yield statement

I came across “Yield” statement in C# 2.0 very recently. I haven’t heard about this and so thought of exploring it a bit. This seems to be handy if you want to generate a list of items. To illustrate this let us consider a Fibonacci series generator example, first without using “Yield” and then using “Yield”.

Fibonacci generator without Yield:

    private IEnumerable<int> getFibonacciList(int num)
        {
            List<int> list = new List<int>();
            int prev = -1;
            int curr = 1;
            for (int i = 0; i < num; i++)
            {
                int next = prev + curr;
                list.Add(next);
                prev = curr;
                curr = next;
            }

            return list;
        }

This method takes an integer as parameter to indicate the length of the Fibonacci series to be generated. As you can see above, we need to create a List<int> and then add the elements to it.

Now, let us see the “Yield” statement version:

        public IEnumerable<int> generate(int num)
        {
            int prev = -1;
            int curr = 1;
            for (int i = 0; i < num; i++)
            {
                int next = prev + curr;
                yield return next;
                prev = curr;
                curr = next;
            }
        }

The above code doesn’t need any List<int> to be created. On first thought, it looks like the compiler generates the additional line of code to declare a List<int>. But in reallity there is lot more than this. If you view the compiled code in .NET Reflector tool you will find lot more code generated.

Now consider the following code that calls the above function:
           
foreach (int i in generate(10))
            {
                Console.WriteLine(i);
            }

When you step through the code in VS debugger, you will find “generate” method is being called 10 times (the value of the passed parameter). What happens is for each iteration of foreach loop, “generate” is called and this method returns as soon as it reaches “yield return”. During the next iteration the execution resumes from the line after “yield return”. This  means that C# maintains the state (like values of variable prev, curr, in our example) for each call (something like closures in javascript).

I am not clear on the real time usage of “Yield” statement. I am planning to read more on this in coming days and hopefully be in better position to list the pros/cons and usages of “Yield” in another post.

Happy coding!!

No comments:

Post a Comment