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!!

Thursday, August 4, 2011

Javascript : Call Vs Apply (Part 2)

This is part 2 of JavaScript Call Vs Apply.

Part 1 explained bit about of switching context in JavaScript and its uses. This part explains how to use Call and Apply for this and what is the difference between Call and Apply.

The only difference between Call and Apply is in how they handle the arguments. In Call you need to pass the arguments (as you do for normal function calls). In Apply you need to pass the arguments as an array. To see this in action, I am going to modify the function used in Part 1 by adding additional arguments:

function displayDetails(argOne, argTwo)
{
          alert(argOne + ‘:’ + argTwo);
}

Following is the syntax to invoke the above function using Call and Apply:

displayDetails.call(object, ‘one’, ’two’);
displayDetails.apply(object, [‘one’,’two’]);

As you could see from above, the only difference is the arguments in Call are sent separately but in Apply it is sent as an array.

One scenario where Apply could be preferred over Call is when you need to pass all the arguments of the parent function to the target function. For example, consider the following code:

function test(testOne, testTwo)
{
          displayDetails.call(this, testOne, testTwo); //works as expected.
displayDetails.apply(this, arguments); //works as expected.
}

Both the lines in the above function work correctly. It you are going to add another parameter to “test” function, then you would need to modify the first line (Call) but not the second (Apply).

function test(testOne, testTwo, testThree)
{
          displayDetails.call(this, testOne, testTwo, testThree); //need to add the additional parameter.
displayDetails.apply(this, arguments); //no changes required.
}

Hope this post was useful.

Happy coding!!