Monday, May 7, 2012

C# : Yield Statement

Used in an iterator block to provide a value to the enumerator object or to signal the end of iteration. It takes one of the following forms:
yield return <expression>;
yield break;
 
You will want to use the yield keyword in methods that return the
type IEnumerable (without any angle brackets), or the type IEnumerable<Type>
with a type parameter in the angle brackets. You need to reference the System.Collections
namespace for the first version, and the System.Collections.Generic namespace for
the second. 

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

// yield-example.cs
using System;
using System.Collections;
public class List
{
    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 
 
 
Example 2: 

using System;
using System.Collections.Generic;
 
    class ExampleYieldReturn
    {
        static void Main(string[] args)
        {
            //with every call it goes to where it left till it encounters yield return
            foreach(int n in GetNumbers())
            {
                Console.WriteLine(n);
            }
 
            Console.ReadLine();
        }
 
    public static IEnumerable<int> GetNumbers()
        {
            Console.WriteLine("Print number 52");
            yield return 52; // will go back to the caller ie foreach
 
            Console.WriteLine("Print number 63");
            yield return 63;// again will go back to the caller ie foreach
 
            Console.WriteLine("Print number 72");
            yield return 72;// again will go back to the caller ie foreach
 
        }
 
    }
 
Output:
Print number 52
52
Print number 63
63
Print number 72
72
Example 3:
 
How to use C# yield to easily return an IEnumerable collection
Using "yield return" instead of "return", you can create IEnumerable collection which you can easily consume in foreach loops and query with LINQ. Notice also that you can just write the method that you want and Visual Studio will allow you to create a stub for it, very convenient.
using System;
using System.Collections.Generic;
using System.Linq;

namespace TestYield
{
    class Program
    {
        static void Main(string[] args)
        {
            //use with foreach
            Console.WriteLine("All ASCII numbers:");
            foreach (int asciiNumber in GetAsciiNumberCollection("This is a test."))
            {
                Console.WriteLine(asciiNumber);
            }

            //use with linq
            Console.WriteLine("Low ASCII numbers:");
            var lowNumbers = from n in GetAsciiNumberCollection("This is a test.")
                             where n <= 90
                             select n;
            foreach (int asciiNumber in lowNumbers)
            {
                Console.WriteLine(asciiNumber);
            }

            Console.ReadLine();
        }

        private static IEnumerable<int> GetAsciiNumberCollection(string line)
        {
            foreach (char letter in line)
            {
                yield return (int)letter;
            }
        }
    }
}

No comments:

Post a Comment