All collections expose the GetEnumerator method. This method returns an object of the IEnumerator type, which allows you to iterate through the collection without having to know anything about its items, not even the count of the items. To retrieve the enumerator for a collection, call its GetEnumerator method by using a statement like the following:
Dim ALEnum As IEnumerator
ALEnum = aList.GetEnumerator
Code language: PHP (php)
The IEnumerator class exposes two methods: the MoveNext and Reset methods. The MoveNext method moves to the next item in the collection and makes it the current item (property Current). When you initialize the IEnumerator object, it’s positioned in front of the very first item, so you must call the MoveNext method to move to the first item. The Reset method does exactly the same thing: It repositions the IEnumerator in front of the first element.
The MoveNext method doesn’t return an item, as you might expect. It returns a True/False value that indicates whether it has successfully moved to the next item. After you have reached the end of the collection, the MoveNext method will return False. Here’s how you can enumerate through an ArrayList collection by using an enumerator:
Dim aItems As IEnumerator
aItems = aList.GetEnumerator
While aItems.MoveNext
{ process item aItems.Current}
End While
Code language: PHP (php)
At each iteration, the current item is given by the Current property of the enumerator. After you reach the last item, the MoveNext method will return False, and the loop will terminate. To rescan the items, you must reset the enumerator by calling its Reset method.
To process the current item, you can call its methods through the aItems.Current object. Because the Current property is an object, you must first cast it to the appropriate type. If the collection holds Rectangles, for example, you can access their sizes by using these expressions:
CType(aItems.Current, Rectangle).Width
CType(aItems.Current, Rectangle).Height
Code language: CSS (css)
The Strict option necessitates the explicit conversion of the Current property to a Rectangle object. In other words, you can’t use an expression such as aItems.Current.Width with the Strict option on (which is the recommended setting for this option).
The event handler in Listing 10.10 populates an ArrayList with Rectangle objects and then iterates through the collection and prints the area of each Rectangle.
Listing 10.10: Iterating an ArrayList with an Enumerator
Dim aList As New ArrayList()
Dim R1 As New Rectangle(1, 1, 10, 10)
aList.Add(R1)
R1 = New Rectangle(2, 2, 20, 20)
aList.Add(R1)
aList.add(New Rectangle(3, 3, 2, 2))
Dim REnum As IEnumerator
REnum = aList.GetEnumerator
Dim R As Rectangle()
While REnum.MoveNext
R = CType(REnum.Current, Rectangle)
Debug.WriteLine((R.Width * R.Height).ToString)
End While
Code language: PHP (php)
The REnum variable is set up and used to iterate through the items of the collection. At each iteration, the code saves the current Rectangle to the R variable, and it uses this variable to access the properties of the Rectangle object (its width and height).
Of course, you can iterate a collection without the enumerator, but with a For Each. . .Next loop. To iterate through a HashTable, you can use either the Keys or the Values collection. The code shown in Listing 10.11 populates a HashTable with Rectangle objects. Then it scans the items and prints their keys, which are strings, and the area of each rectangle.
Listing 10.11: Iterating a HashTable with Its Keys
Dim hTable As New HashTable()
Dim r1 As New Rectangle(1, 1, 10, 10)
hTable.Add("R1", r1)
r1 = New Rectangle(2, 2, 20, 20)
hTable.Add("R2", r1)
hTable.add("R3", New Rectangle(3, 3, 2, 2))
Dim key As Object
Dim R As Rectangle
For Each key In hTable.keys
R = CType(hTable(key), Rectangle)
Debug.WriteLine(String.Format( _
"The area of Rectangle {0} is {1}", _
key.ToString, R.Width * R.Height))
Next
Code language: PHP (php)
The code adds three Rectangle objects to the HashTable and then iterates through the collection using the Keys properties. Each item’s key is a string (R1, R2, and R3). The Keys property is itself a collection and can be scanned with a For Each. . .Next loop. At each iteration, we access a different item through its key with the expression hTable(key). The output produced by this code is shown here:
The area of Rectangle R1 is 100
The area of Rectangle R3 is 4
The area of Rectangle R2 is 400
Alternatively, you can iterate a HashTable with an enumerator, but be aware that the GetEnumerator method of the HashTable collection returns an object of the IDictionaryEnumerator type, not an IEnumerator object. The IDictionaryEnumerator class is quite similar to the IEnumerator class, but it exposes additional properties. They are the Key and Value properties, and they return the current item’s key and value. The IDictionaryEnumerator class also exposes the Entry property, which contains both the key and the value. You can access the current item’s key and value either as DEnum.Key and DEnum.Value, or as DEnum.Entry.Key and DEnum.Entry.Value. The DEnum variable is a properly declared enumerator for the HashTable:
Dim DEnum As IDictionaryEnumerator
Code language: PHP (php)
Assuming that you have populated the hTable collection with the same three Rectangle objects, you can use the statements in Listing 10.12 to iterate through the collection’s items.
Listing 10.12: Iterating a HashTable with an Enumerator
Dim hEnum As IDictionaryEnumerator
hEnum = hTable.GetEnumerator
While hEnum.MoveNext
Debug.WriteLine( _
String.Format(”The area of rectangle ” & _
”{0} is {1}”, hEnum.Key, _
CType(hEnum.Value, Rectangle).Width * _
CType(hEnum.Value, Rectangle).Height))
End While
Code language: PHP (php)
If you execute these statements after populating the HashTable collection with three Rectangles, they will produce the same output as Listing 10.11.
The Enumerations project shows how to iterate through an ArrayList and a HashTable with and without an enumerator. The code should be quite familiar to you by now, so I do not list it here. You can open the project and examine its code and routines.