|Develop custom enumerating functionality and take advantage of iteration through non-collection-based classes.
ne of the coolest things I like about the .NET Framework is the way collections are designed and handled. On the surface, you simply see many types of collections, stored in the System.Collections namespace. In fact, there is another namespace directly under this one called System.Collections.Specialized, which contains even more collection types, including one that mimics the old-fashioned Visual Basic 6.0 collection. What is not completely obvious is how these collections work internally. While this is not a tutorial on .NET collections, it's important to understand the basics of what lies beneath the surface of all these new collection types.
Under the Hood of Collections
The heart of all the collection classes in the .NET Framework is really a set of interfaces. Which interfaces are implemented and how they are implemented determine the capabilities and behavior of any particular collection class. The two main interfaces used in collection classes are ICollection and IList. ICollection provides the functionality for item counts, enumerating, and synchronization. IList defines the methods and properties that allow the storage of items and all functionality to address that storage (add, remove, etc.). The enumeration capabilities are defined in the IEnumerable and IEnumerator interfaces. The ICollection interface, in fact, inherits from the IEnumerable interface, thus "inheriting" its interface. The way these interfaces are implemented determine if the items will be stored in a particular order (sorted list, stack, or queue), if they are hashed for storage, and other behavior. The implementation also determines how items in storage get retrieved; for example, by index, by key, 'popped' in the case of a Stack, 'dequeued' in the case of a Queue, etc.
|This article assumes a basic knowledge of collection classes for the sake of the quick-review at the beginning.
Custom implementations of the interfaces mentioned above allow you to add some really slick functionality in your custom collection classes. In fact, the .NET Framework gives you a head start when designing your own collection classes by exposing two abstract classes, CollectionBase and DictionaryBase. These abstract classes already implement the fore-mentioned interfaces and provide the basic implementation, allowing you to further extend them for your own needs. Custom collection classes that inherit from these base classes or that are developed from scratch by totally custom-implementing all the necessary interfaces can expose their lists for iteration using standard For Each
in C#) as can all the standard collection types included with the .NET Framework (ArrayList, Hashtable, etc.).
In VB .NET:
For Each s_Name As String In o_MyCollectionOfNames
' Do whatever you want with s_Name
foreach(string s_Name in o_MyCollectionOfNames)
// Do whatever you want with s_Name
The code above should be familiar to all of you, even those of you who have not made the transition from Visual Basic 6.0 yet. A tutorial that describes how to use these interfaces and abstract classes is perhaps an excellent topic for another article, but here I will concentrate on just two of these interfaces: IEnumerable and IEnumerator. The class I will iterate through is not a collection class because it does not inherit from either CollectionBase nor DictionaryBase, nor does it implement ICollection or IList. In fact, my class will not even contain a collection; it is just a couple of simple properties that define beginning and ending markers. Intrigued yet? Let's get going.