Use the yield statement in C#

[yield]

An enumeration is a sequence of values that a program can enumerate over, for example, by using a foreach loop. In C# you can use the yield statement to make a method that returns an enumeration. The method that builds the enumeration should return a type of IEnumerable. It should use yield return to indicate a value that should be returned in the enumeration.

The following code shows how this example builds a Primes method that returns the prime numbers below a given maximum value.

// Return primes by using the Sieve of Eratosthenes.
private static IEnumerable<int> Primes(int max)
{
    bool[] not_prime = new bool[max + 1];
    for (int i = 2; i <= max; i++)
    {
        // See if i is prime.
        if (!not_prime[i])
        {
            // The number i is prime. Return it.
            //Console.WriteLine("Yielding " + i);
            yield return i;

            // Knock out multiples of i.
            for (int j = i * 2; j <= max; j += i)
                not_prime[j] = true;
        }
    }
}

In this example the method is static because it doesn’t need to know anything about the form, but in general an enumeration method need not be static.

The method returns an enumeration of integers so its return type is IEnumerable<int>.

The code uses the Sieve of Eratosthenes to find prime numbers. For an explanation of that method, see Use the Sieve of Eratosthenes to find prime numbers in C#.

The only difference between this program and the previous one is in what the method does when it finds a prime. Instead of directly adding the value to the form’s ListBox, the enumeration method uses a yield return statement to add the value to the enumeration.

The following code shows how the program uses the enumeration.

// Fill the ListBox with primes.
private void Form1_Load(object sender, EventArgs e)
{
    foreach (int prime in Primes(250))
    {
        //Console.WriteLine("Got " + prime);
        lstPrimes.Items.Add(prime);
    }
}

When the form loads, this code uses a foreach loop to enumerate the values returned by the Primes method, adding each to the form’s ListBox.

So how is this different from writing a Primes method that simply builds a List<int> or some other collection and fills it with values? The result is similar but the method is very different. When the program invokes the Primes method, that method starts executing. When that method executes a yield statement, control returns to the calling code to process the yielded value. When the foreach loop continues to the next value, control returns to the Primes method so it can generate another value.

If you uncomment the Console.WriteLine statements in the code, you’ll see that each “Yielding” message is immediately followed by a “Got” message. If the Primes method built and returned a collection of values, then the code would produce all of the “Yielding” messages first and then all of the “Got” messages. Because it uses yield return, the method returns to the Form_Load event handler’s foreach after it generates each value.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in algorithms, mathematics and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *