Subscribe

RSS Feed (xml)

Implementing IEnumerable and IEnumerator

As mentioned earlier, normally it is easier (and better) to use a foreach loop to cycle through a collection than it is to explicitly use IEnumerator methods. However, understanding the operation of these interfaces is important for another reason: If you want to create a class that contains objects that can be enumerated via a foreach loop, then that class must implement IEnumerator. It must also implement IEnumerable. In other words, to enable an object of a class that you create to be used in a foreach loop, you must implement IEnumerator and IEnumerable, using either their generic or non-generic form. Fortunately, because these interfaces are so small, they are easy to implement.
Here is an example that implements the non-generic versions of IEnumerable and IEnumerator so that the contents of the array encapsulated within MyClass can be enumerated.
// Implement IEnumerable and IEnumerator.
using System;
using System.Collections;

class MyClass : IEnumerator, IEnumerable {
  char[] chrs = { 'A', 'B', 'C', 'D' };
  int idx = -1;
  // Implement IEnumerable.
  public IEnumerator GetEnumerator() {
    return this;
  }

  // The following methods implement IEnumerator.

  // Return the current object.
  public object Current {
    get {
      return chrs[idx];
    }
  }

  // Advance to the next object.
  public bool MoveNext() {
    if(idx == chrs.Length-1) {
      Reset(); // reset enumerator at the end.
      return false;
    }

    idx++;
    return true;
  }

  // Reset the enumerator to the start.
  public void Reset() { idx = -1; }
}

class EnumeratorImplDemo {
  public static void Main() {
    MyClass mc = new MyClass();

    // Display the contents of mc.
    foreach(char ch in mc)
      Console.Write(ch + " ");

    Console.WriteLine();

    // Display the contents of mc, again.
    foreach(char ch in mc)
      Console.Write(ch + " ");

    Console.WriteLine();
  }
}
Here is the output:
A B C D
A B C D
In the program, first examine MyClass. It encapsulates a small char array that contains the characters A through D. An index into this array is stored in idx, which is initialized to 1. MyClass then implements both IEnumerator and IEnumerable. GetEnumerator( ) returns a reference to the enumerator, which in this case is the current object. The Current property returns the next character in the array, which is the object at idx. The MoveNext( ) method advances idx to the next location. It returns false if the end of the collection has been reached and true otherwise. Reset( ) sets idx to 1. Recall that an enumerator is undefined until after the first call to MoveNext( ). Thus, in a foreach loop, MoveNext( ) is automatically called before Current. This is why idx must initially be 1; it is advanced to zero when the foreach loop begins. A generic implementation would work in a similar fashion.
Inside Main( ), an object of type MyClass called mc is created, and the contents of the object are twice displayed by use of a foreach loop.

No comments:

Post a Comment

Archives

LocalsAdda.com-Variety In Web World

Fun Mail - Fun in the Mail