Answer for Puzzle 2

public IEnumerator GetEnumerator()

{

for (int index = 0; index < values.Length; index++)

{

yield return values[(index + startingPoint) % values.Length];

}

}

This small code block of c#2 replaces the entire Iterator class. The trick here is in the yield return statement.  When you write this statement you actually ask .Net to create a state machine for you. This statement is keeping track of what we were doing when we last returned a value.  Every time the yield return statement is hit the method returns but when the calling method ask for the next element in the IEnumerable collection you re-enter the method just after the last yield return statement as you would never have left it. All the state of the local variables inside the IEnumerator method is preserved.  What is also important to understand is that trick is not performed by the runtime but by the compiler so you don’t incurs real performance lost.

Puzzle 2: iterators using the yield statement (intermediate)

Remove the iterator class from the listing and replace the call to the iterator class, inside the iteration sample(line 29), by using the yield operator of C#2.

The output of the Problem() method should remain the same.

  1: using System;
  2: using System.Collections;
  3: 
  4: namespace Puzzles
  5: {
  6: 
  7:     public class Enumarators
  8:     {
  9:         public static void Problem()
 10:         {
 11:             var myValues = new[] { "a", "b", "c", "d" };
 12:             var col = new IterationSample(myValues);
 13:             foreach (var x in col)
 14:             {
 15:                 Console.WriteLine(x);
 16:             }
 17:         }
 18: 
 19:         public class IterationSample : IEnumerable
 20:         {
 21:             internal object[] values;
 22: 
 23:             public IterationSample(object[] values)
 24:             {
 25:                 this.values = values;
 26:             }
 27:             public IEnumerator GetEnumerator()
 28:             {
 29:                 return new Iterator(this);  //Change this line by using yield
 30:             }
 31:         }
 32: 
 33:         public class Iterator:IEnumerator
 34:         {
 35:             IterationSample parent;
 36:             int position;
 37: 
 38:             internal Iterator(IterationSample parent)
 39:             {
 40:                 this.parent = parent;
 41:                 position = -1;
 42:             }
 43:             public bool MoveNext()
 44:             {
 45:                 if (position != parent.values.Length)
 46:                 {
 47:                 position++;
 48:                 }
 49:                 return position < parent.values.Length;
 50:             }
 51:             public object Current
 52:             {
 53:                 get
 54:                 {
 55:                     if (position==-1 || position==parent.values.Length)
 56:                     {
 57:                      throw new InvalidOperationException();
 58:                     }
 59:                     return parent.values[position];
 60:                 }
 61:             }
 62:             public void Reset()
 63:             {
 64:                 position = -1;
 65:             }
 66:         }
 67:     }
 68: }
 69: