IEnumerable is a great example of an interface. IEnumerable defines just one method: GetEnumerator. This method returns an Enumerator object for a collection and that lets you step through the collection with the For ... Each syntax.
In turn, the Enumerator object implements the IEnumerator interface of the System.Collections namespace. (So this is an interface implementation that is nested two deep.) The IEnumerator interface exposes the Current property and the Reset and MoveNext methods. This gives you even more flexibility beyond For-Each loops.
To demonstrate the whole thing, let's expand on the "party" idea and define a new class that implements both IEnumerable and IEnumerator. Our new class will list different types of parties to help us fill out our busy engagement schedule. The graphic below shows the main program and the result.
--------
Click Here to display the illustration
Click the Back button on your browser to return
--------
First, we need to define a class to implement IEnumerable. Here's a start ...
Public Class Parties
Implements IEnumerator, IEnumerable
Public Function GetEnumerator() _
As IEnumerator _
Implements IEnumerable.GetEnumerator
Return CType(Me, IEnumerator)
End Function
This satisfies the requirement of IEnumerable because it implements GetEnumerator. How does it do that? It simply uses the CType operator to change the class itself into an IEnumerator and returns it. But to do that, the code now has to implement the Current property and provide code for the Reset and MoveNext methods. There are two major ways to do that and we'll look at them next.
The first way to implement the property and two methods required by the IEnumerator interface is to simply code them directly right in the same class. Here's the code to do that:
Private position As Integer = -1
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
position += 1
Return (position < engagements.Length)
End Function
Public Sub Reset() Implements IEnumerator.Reset
position = -1
End Sub
Public ReadOnly Property Current() As Object Implements IEnumerator.Current
Get
Return engagements(position)
End Get
End Property
The second major way to implement IEnumerator is to pass the collection to a class that implements GetEnumerator. The System.Collection class does the job nicely! (Ain't it wunnerful how the .NET Framework just fits together like a fine watch?) Replace the earlier GetEnumerator function with this one:
Public Function GetEnumerator() _
As System.Collections.IEnumerator _
Implements System.Collections.IEnumerable.GetEnumerator
Return engagements.GetEnumerator
End Function
Then delete the internal coding for the Current property amd the Reset and MoveNext methods. Also, since this class isn't implementing GetEnumerator() anymore, replace ...
Implements IEnumerator, IEnumerable
... with ...
Implements IEnumerable
There is just one loose end to clear up at this point: There is no engagements collection. You could get this from a database or another class, but the simple thing to do is to code it inline right here.
Private engagements() As Party = New Party() _
{ _
New Party("CockTail", #11:00:00 PM#), _
New Party("Political", #7:00:00 PM#), _
New Party("Neigborhood", #8:30:00 PM#), _
New Party("Kids Birthday", #4:00:00 PM#), _
New Party("Animal House", #6:00:00 AM#) _
}
VB.NET 2008 provides yet another dimension of IEnumberable flexibility: IEnumerable(T). This is an enhancement that fits into a technology that usually goes by the name "generics". I described this when it was introduced in the article Generics! Cleaner Data - Faster Code!. Check out that article for an introduction to these added benefits.
All the code described in this article can be downloaded here.

