Ended up with the following for my ICollection interface:
The next issue on the plate is how to get to the elements in the collection. I stated earlier that i don’t necessarily want to limit myself to finite collections, so indexing into the collection seems out. The only other option i see it some way to query collection for all of it’s elements one at a time. i.e. implementing the Iterator pattern (see Design Patterns). However, there are several choices you can make (with corresponding tradeoffs). The first thing I need to decide on is if these collections are going to support internal or external iteration (or both). External iteration is done with the pattern we commonly see in the BCL. I.e.
Calling GetEnumerator returns an IEnumerator that one can foreach across to access all elements. Alternatively we can use internal iteration which looks like:
void Iterate(Predicate<A> p);
When you call this you pass a delegate that will be performed on each element in the list. The delegates return value says if we should continue. Returning true is equivalent to “continue”ing in a foreach, returning false is equivalent to “break”ing out of a foreach. I might also provide:
void Iterate(Operator<A> p);
Which will iterate over every element without stopping. An example of using both is shown here:
Or, we could have something like:
I’m not sure which i prefer, although I am strongly leaning toward Iterate. It allows for far easier implementation of the Iterator (try implementing GetEnumerator on a tree versus Iterate on a tree). However, you are more limited in what you can do. For example, if sublasses return specialized IEnumerators (like IListEnumerator or ITreeEnumerator) then this can’t really be expressed well in the Iterate model. Also, because you are iterating all at once, it makes it difficult to weave enumerators together. (try writing ArrayCollection.Equals with just Iterate versus ArrayCollection.Equals using GetEnumerator).