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