The Iterator Design Pattern separates the logic to navigate a collection into a different layer, so your collections won't need to understand how to iterate through its elements.
This pattern exists in a class that will hold the elements and another class that will navigate.
An example from scratch could be a collection of stories that are iterated using a StoryIterator and not by the collection itself as in the following:
- public class StoryCollection
- {
- private ArrayList items = new ArrayList();
-
- public int Count
- {
- get
- {
- return items.Count;
- }
- }
-
- public Story this[int index]
- {
- get
- {
- return items[index] as Story;
- }
- set
- {
- items.Insert(index, value);
- }
- }
-
- public StoryEnumerator GetEnumerator()
- {
- return new StoryEnumerator(this);
- }
- }
-
- public class StoryEnumerator
- {
- private int currentIndex = -1;
-
- private StoryCollection collection;
-
- public StoryEnumerator(StoryCollection collection)
- {
- this.collection = collection;
- }
-
- public Story Current
- {
- get
- {
- if (currentIndex < 0 || collection.Count <= currentIndex)
- return null;
-
- return collection[currentIndex];
- }
- }
-
- public bool MoveNext()
- {
- if (collection.Count == (currentIndex + 1))
- return false;
-
- ++currentIndex;
-
- return true;
- }
-
- public void Reset()
- {
- currentIndex = -1;
- }
- }
And to use it we could test several scenarios as in the following:
The only thing the collection does is worry about storing items. This example shows how it would look from scratch,
but in .NET we already have the IEnumerable<T> and IEnumerator<T> interfaces for that purpose. All commonly-used collections already implement those interfaces. If a class implements these interfaces then the collection will be available on a foreach loop.