User Tools

Site Tools


notes:csharp:yield

Yield in C#

The yield statement produces an enumerator, not just a list of items. It's a way of supporting a foreach iteration without implementing the entire IEnumerable interface.

The yield return statement allows you to return one element during each iteration. This makes it possible to iterate through data without reading all of it into memory in one turn.

Example: Create an enumerator returning a power of 2 in each iteration:

// The Power method has to have a return type of IEnumerable, IEnumerator, or one of the generic equivalents. 
public IEnumerable Power(int number, int exponent)
{
    int i = 0;
    int result = 1;
    while (++i < exponent)
    {
        result = result * number;
 
        // The returned element is of type object.
        yield return result;
    }
}
...
// Display the powers of 2: 2 4 8 16 32 64 128 256
foreach (int i in Power(2, 8)) 
{ 
    Console.Write($"{i} "); 
} 

Example: Create a generic enumerator returning a value of an enum in each iteration:

public enum WeekdayEnum
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}
...
private IEnumerable<WeekdayEnum> Weekday
{
    // return enum values in a different order than defined
    get
    {
        yield return WeekdayEnum.Monday;
        yield return WeekdayEnum.Tuesday;
        yield return WeekdayEnum.Wednesday;
        yield return WeekdayEnum.Thursday;
        yield return WeekdayEnum.Friday;
        yield return WeekdayEnum.Saturday;
        yield return WeekdayEnum.Sunday;
    }
}
...
foreach (WeekdayEnum d in Weekday)
{
    // Display weekdays from Monday to Sunday.
    Console.WriteLine(d.ToString());
}

Example: Create an enumerator returning a line from a text file in each iteration:

IEnumerable<string> ReadLines(string filename)
{
    using (TextReader reader = File.OpenText(filename))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}
...
foreach (string line in ReadLines("data.txt"))
{
    Console.WriteLine(line);
}

Example: Implement an enumerator that utilizes an indexer:

class Mapping
{
    private int[] arr = new int[] { 5, 8, 12, 7, 3 };
 
    // indexer
    public int this[int i]
    {
        get
        {
            // Here goes a complex algorithm to retrieve a value by the index...
            return arr[i];
        }
    }
 
    // Note that we return IEnumerator rather than IEnumerable.
    public IEnumerator GetEnumerator()
    {
        for (int i = 0; i < arr.Length; i++)
        {
            yield return this[i];
        }
    }
}
...
Mapping collection = new Mapping();
 
foreach (int i in collection)
{
    Console.WriteLine(i); // prints: 5,8,12,7,3
}
notes/csharp/yield.txt · Last modified: 2016/12/14 by admin