C# Using Yield to Produce Iterators

1. .Net allows you to loop around objects which implement IEnumerable with the foreach construct, e.g.
    char[] letters = new char[] { 'a', 'b', 'c', 'd' };
    foreach (char c in letters)
    {
        Console.WriteLine(c);
    }
But we're a bit stuck if we ever have a collection of objects which don't have an iterator.
2. Luckily, the yield operator allows us to create a method which returns an iterator which has been populated with anything we want, e.g.
    public static IEnumerable<int> CountUp(int lower, int upper)
    {
        int counter = lower;
        while (counter <= upper)
        {
            yield return counter;
            counter++;
        }
    }
This returns an IEnumerable object with integer values from lower to upper. We can call it in our code:
    foreach (int thing in CountUp(1, 10))
    {
        Console.WriteLine(thing);
    }
3. You can be as stupid as you like in your iterator method... imagine we had an object called PersonDetails which contained many fields, but we wanted to loop through the string fields looking for something. So we can use foreach, we can construct a 'dummy' iterator, reterning just the items we need:
    public static IEnumerable<string> AllPersonStrings(PersonDetails person)
    {
        yield return person.name;
        yield return person.townofbirth;
        yield return person.nationality;
        yield return person.username;
        yield return person.securityquestion;
    }
Now we can iterate around these things looking for whatever we want
    foreach (string thing in AllPersonStrings(thisPerson))
    {
        //code here to search for something in this particular string
    }
4. Iterators do not need to be primitive in type. Imagine we have a small class with two fields and a constructor:
    class Thing
    {
        public int Rank;
        public string Name;

        public Thing(int rank, string name)
        {
            this.Rank = rank;
            this.Name = name;
        }
    }
We can now create an IEnumerable object which contains Things:
    public static IEnumerable<Thing> ManyThings(int lower, int upper)
    {
        int counter = lower;
        while (counter < upper)
        {
            Thing oneThing = new Thing(counter, "Name" + counter.ToString());
            yield return oneThing;
            counter++;
        }
    }
Now we can iterate through our list of Things using a foreach:
    foreach (Thing thing in ManyThings(1, 10))
    {
        Console.WriteLine(thing.Name);
    }
And that is all there is to constructing IEnumerable iterators for your foreach loops.