A foreach
statement is a consumer of an enumerator.
An iterator is a producer of an enumerator.
In this example, we use an iterator to return a sequence of Fibonacci numbers:
using System; using System.Collections.Generic; class Main { static void Main() { foreach (int fib in Fibs(6)){ Console.Write (fib + " "); } } static IEnumerable<int> Fibs (int fibCount) { for (int i = 0, prevFib = 1, curFib = 1; i < fibCount; i++) { yield return prevFib; int newFib = prevFib+curFib; prevFib = curFib; curFib = newFib; } } }
A yield
return statement return
the next element from this enumerator.
An iterator is a method, property, or indexer that contains one or more yield
statements.
An iterator must return one of the following four interfaces:
// Enumerable interfaces System.Collections.IEnumerable System.Collections.Generic.IEnumerable<T> // Enumerator interfaces System.Collections.IEnumerator System.Collections.Generic.IEnumerator<T>
Multiple yield statements are permitted. For example:
class Test { static void Main() { foreach (string s in Foo()) Console.WriteLine(s); // Prints "One","Two","Three" } static IEnumerable<string> Foo() { yield return "One"; yield return "Two"; yield return "Three"; } }
The yield break
statement indicates that the iterator block should exit early,
without returning more elements.
The following code shows how to use yield break:
static IEnumerable<string> Foo (bool breakEarly) { yield return "One"; yield return "Two"; if (breakEarly) yield break; yield return "Three"; }
A return statement is illegal in an iterator block, use yield break instead.
The following code shows how to output even Fibonacci numbers only:
using System; using System.Collections.Generic; class Main { static void Main() { foreach (int fib in EvenNumbersOnly (Fibs(6))) Console.WriteLine (fib); } static IEnumerable<int> Fibs (int fibCount) { for (int i = 0, prevFib = 1, curFib = 1; i < fibCount; i++) { yield return prevFib; int newFib = prevFib+curFib; prevFib = curFib; curFib = newFib; } } static IEnumerable<int> EvenNumbersOnly (IEnumerable<int> sequence) { foreach (int x in sequence) if ((x % 2) == 0) yield return x; } }