CHAPTER 8 WORKING WITH INTERFACES
public IEnumerator GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
}
After you have updated your Garage type, you can safely use the type within the C# foreach
construct. Furthermore, given that the GetEnumerator() method has been defined publicly, the object
user could also interact with the IEnumerator type:
// Manually work with IEnumerator.
IEnumerator i = carLot.GetEnumerator();
i.MoveNext();
Car myCar = (Car)i.Current;
Console.WriteLine("{0} is going {1} MPH", myCar.PetName, myCar.CurrentSpeed);
However, if you prefer to hide the functionality of IEnumerable from the object level, simply make
use of explicit interface implementation:
IEnumerator IEnumerable.GetEnumerator()
{
// Return the array object's IEnumerator.
return carArray.GetEnumerator();
}
By doing so, the casual object user will not find the Garage’s GetEnumerator() method, while the
foreach construct will obtain the interface in the background when necessary.
Source Code The CustomEnumerator project is located under the Chapter 8 subdirectory.
Building Iterator Methods with the yield Keyword
In earlier versions of the .NET platform, when you wanted to build a custom collection (such as Garage)
that supported foreach enumeration, implementing the IEnumerable interface (and possibly the
IEnumerator interface) was your only option. However, there’s an alternative way to build types that
work with the foreach loop via iterators.
Simply put, an iterator is a member that specifies how a container’s internal items should be
returned when processed by foreach. While the iterator method must still be named GetEnumerator(),
and the return value must still be of type IEnumerator, your custom class does not need to implement
any of the expected interfaces.
To illustrate, create a new Console Application project named CustomEnumeratorWithYield and
insert the Car, Radio, and Garage types from the previous example (again, renaming your namespace
definitions to the current project if you like). Now, retrofit the current Garage type as follows:
public class Garage : IEnumerator
{
private Car[] carArray = new Car[4];
...
// Iterator method.
305