using System;
using System.Collections;
using System.Collections.Generic;
class Program {
// *** before: ***
// to be usable in foreach a type had to carry an enumerator written by
// hand: a state field, MoveNext, Current and Reset
class EvenNumbersOld : IEnumerable {
int bound;
public EvenNumbersOld(int bound) { this.bound = bound; }
public IEnumerator GetEnumerator() { return new Enumerator(bound); }
class Enumerator : IEnumerator {
int bound, current;
public Enumerator(int bound) { this.bound = bound; this.current =
0; }
public bool MoveNext() { current += 2; return current <= bound; }
public object Current { get { return current; } }
public void Reset() { current = 0; }
}
}
// *** in version 2.0: ***
// yield return writes that state machine for us
static IEnumerable<int> EvenNumbers(int bound) {
for (int n = 2; n <= bound; n += 2)
yield return n; // the method pauses here
}
static IEnumerable<int> FirstThree(IEnumerable<int> source) {
int taken = 0;
foreach (int n in source) {
if (taken == 3) yield break; // stop early
taken++;
yield return n;
}
}
static void Main() {
foreach (int n in new EvenNumbersOld(10)) Console.Write(n + " ");
Console.WriteLine();
foreach (int n in EvenNumbers(10)) Console.Write(n + " ");
Console.WriteLine();
// the values are produced one by one, so an endless source is fine
foreach (int n in FirstThree(EvenNumbers(int.MaxValue))) Console.Write(
n + " ");
Console.WriteLine();
}
}