The foreach is a powerful construct found in C# and Visual Basic.NET that allows you to iterate through a collection of objects. Managed C++ is missing this useful construct, so I wrote this article to show you how to add it to your programming arsenal.
Managed C++ provides many powerful collection classes for the storage and retrieval of data types. An interesting feature of these classes is that they all provide an IEnumerable interface. Its only purpose is to expose the GetEnumerator() method, which returns a pointer to an object that implements the IEnumerator interface. The IEnumerator interface exposes methods that allow all collections to be iterated through in the same way. It is with this IEnumerator interface that we can implement the foreach looping construct.
The IEnumerator interface is fairly simple. You use the MoveNext() method to advance the enumerator to the next object in the collection and then you grab the object out of the collection using the Current property. You know you have reached the end of the collection when MoveNext() returns false. If you want to move the enumerator back to the start of the collection, you call the Reset() method.
We want the foreach looping construct to hide all the details of the IEnumerable and IEnumerator interfaces, so we will encapsulate all the details within the Foreach class, as shown in Listing A.
We're going to need two private member variables. The first variable, collection, we will store off the current collection class so that we can check to see whether this is a new loop or the continuation of an existing loop. The second variable is enumerator. We will save the current enumerator so that we can continue where we left off in the collection when iterating.
The foreach() method takes a pointer to a pointer Object and any collection class as parameters. To be more accurate, the second parameter takes any class that implements the IEnumerable interface because the Array class is not a member of the System::Collections namespace. I would argue, though, that an Array is also a collection.
The foreach() method starts by checking to see whether the same collection is being enumerated. The first time the collection class is being enumerated, the enumerator is retrieved and stored along with the collection. From here on, it is just standard enumerator code. A call is made to the MoveNext() method, and then the object is extracted from the collection using the Current property. We save the return value of the MoveNext() method so that it can be returned by the foreach() method. The Current Property is saved on the out object.
We end the foreach() method by resetting the enumerator when the last item has been retrieved so that the foreach() method can be run again on the same collection if it is called again immediately.
To implement the foreach() method for a collection class, you can be completely ignorant of the IEnumerable or IEnumerator interfaces, as you can see in Listing B.
All you need is a collection class, an instance of a Foreach class, and an Object variable to store the retrieved enumerated collection value. Obviously, the foreach is a method call and not an iterative construct, so we have to place it within a while statement for it to run in a loop, but that is hardly difficult as you can see in Listing B.
It is a little trickier to use the Foreach class in an embedded fashion because the enumerator gets overwritten in the inner loop. To fix this, you need two instances of the Foreach class: one for the outer loop and one for the inner loop, as shown in Listing C.
Notice that the type of collection is immaterial, since we use both an Array and an ArrayList. We could have used a Stack, Queue, HashTable, or any of the other .NET Framework class library collection classes.
If you add a main function as shown in Listing D, the program output will look something like Figure A.
|Results of Listing D|
The foreach is a powerful looping construct for .NET collections found in the C# and Visual Basic.NET languages. Unfortunately, it's missing from Managed C++. This article provided you with the means of implementing your own version of foreach and then showed how to add this implementation to your programs.