Friday 15 April 2011

Yield Keyword in C#

Introduction:

The yield keyword was new feature in C# 2.0 and is used to simplify the implementation of enumeration in custom classes.

Following are two forms of the yield statement.

1. yield return ;

2. yield break;

· In a yield return statement, expression is evaluated and returned as a value to the enumerator object; expression has to be implicitly convertible to the yield type of the iterator.

· In a yield break statement, control is unconditionally returned to the caller of the iterator,



Problem:

The yield keyword simplifies the implementation of iterable collections, but it also allows us to move beyond collections and into result sets. Using the yield keyword, we can convert calculated sequences into collections.

Let me give an example. Let’s say that I am calculating the sequence of square roots for all numbers.

Assuming for the moment that we do create an infinite array, let’s look at how those numbers would be generated without using the yield keyword.

There would be a piece of code that would call the algorithm to generate the sequence of numbers. The sequence of numbers would be added to an array, which is returned to the calling code when the algorithm has completed. Yet we are calculating an infinite sequence of numbers, meaning that the algorithm will never end and the array will never be complete.

Of course, in reality, algorithms do end, and arrays do become complete. But the example illustrates that if you were to generate a collection that could be iterated, you must first generate the collection and then iterate the collection. This would mean you first allocate the space for an array and then fill the array, resulting in a not-as-efficient solution. The yield keyword is more efficient, because it allows a calculation to generate numbers on the fly.



Implementation:

yield return statement:

In the following example, the yield statement is used inside an iterator block, which is the method ComputePower(int number, int power). When the Power method is invoked, it returns an enumerable object that contains the powers of a number.

using System;

using System.Collections.Generic;

public class Program

{

static void Main()

{

// Compute two with the exponent of 30.

foreach (int value in ComputePower(2, 30))

{

Console.Write(value);

Console.Write(" ");

}

Console.WriteLine();

}

public static IEnumerable<int> ComputePower(int number, int exponent)

{

int exponentNum = 0;

int numberResult = 1;

// Continue loop until the exponent count is reached.

while (exponentNum < exponent)

{

// Multiply the result.

numberResult *= number;

exponentNum++;

// Return the result with yield.

yield return numberResult;

}

}

}



Output:

2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288

1048576 2097152 4194304 8388608 16777216 33554432 67108864 134217728 268435456 536870912 107374182



yield break statement:

If inside this loop I want to abort the iteration and return, I do this through the yield break. The yield break will do more than a normal break, as it will return from the method, and not only from the for-loop.

E.g.: If I have to consecutive for-loops in the same method, both using yield, and I do yield break in the first, the second for-loop will never be executed:

public static IEnumerable<string> GetMoreResults()

{

for (int i = 0; i < 20; i++)

{

yield return "Value " + i;

yield break;

}

//Do something else

for (int i = 0; i < 20; i++)

{

yield return "Another value " + i;

}

}

Here I will only get one value returned in my IEnumerable, as the yield break will end the method execution.



Limitation:

· Unsafe blocks are not allowed.

· Parameters to the method, operator, or accessor cannot be ref or out.

· A yield return statement cannot be located anywhere inside a try-catch block. It can be located in a try block if the try block is followed by a finally block.

· A yield break statement may be located in a try block or a catch block but not a finally block.

· A yield statement cannot appear in an anonymous method.


Ref:

http://en.csharp-online.net/CSharp_Coding_Solutions%E2%80%94What_Does_Yield_Keyword_Generate

http://iserialized.com/a-quick-start-guide-to-yield-return-and-yield-break/

http://msdn.microsoft.com/en-us/library/9k7k7cf0(v=VS.100).aspx

No comments:

Post a Comment