Internal and External Iterators
I've updated ICollection<A> in the following manner:
public interface ICollection<A> : IEnumerable<A>
/// Previous stuff
/// Iterates over the members in this collection applying 'p' to each element.
/// The return value of p(element) indicates if iteration should proceed. i.e.
/// If p(element) returns false then iteration stops. If it returns true then
/// iteration continues
/// <param name="p">The function to apply to the elements in this Collection.
/// The return value says when iteration should continue</param>
void Iterate(Predicate<A> p);
It not only extends IEnumerable<A> so you can foreach over collections, but it also provides an internal iterator. This exists because for a vast majority of cases, writing an efficient internal iterator is far easier than the equivalant external one. I mentioned the case of an external iterator on a tree, and I recommend you try it and see what it's like
Now: since I'm writing a library one of my core goals is to make extensibility very easy. I.e. i would like to provide 'almost' implementation with almost all functionality basically implemented. I say 'basically' because I mean that the implementation might be quite dumb and enneficient, however subclasses will be free to override with specialized versions for themselves. In other words, I'd like abstract implementations with almost all the work taken care of for you. So I started to write AbstractCollection<A> and I ended up in an interesting situation:
public abstract class AbstractCollection<A> : ICollection<A>
public void Iterate(Predicate<A> p)
foreach (A element in this)
public IEnumerator<A> GetEnumerator()
yield return element;
As you can see, I have a pair of mutually recursive methods. This is by design. The intent is that subclasses only need implement one of the methods in order to get both. I.e. if you implement GetEnumerator() then you will get Iterator(Predicate<A> p) for free, and vice-versa. However when I tried to compile I was met with the dissapointing error:
Error 1 The yield statement cannot be used inside anonymous method blocks
Oh noes! How do I work around this? Is it possible to define GetEnumerator in terms of Iterate? If you can think of a way how, let me know!