I have a C# class which needs to process a sequence of items (IEnumerable<T>
) across a bunch of methods, so I cannot simply foreach
inside a method. I call .GetEnumerator()
and pass this IEnumerator<T>
around and it works great giving me the flexibility I need while looping through a single sequence.
Now I want to allow others to add logic into this process. The most natural way to do this is give them an interface with a method that accepts the IEnumerator<T>
. Easy, done, and it works.
But I'm concerned that this is an anti-pattern. They have to know that the IEnumerator<T>
has already had .MoveNext()
called, so they can simply access .Current
. Plus I don't see any precedent for using IEnumerator<T>
in interfaces to be implemented.
- What pitfalls am I not considering?
- Is there another pattern which will allow me this same efficient mechanism (i.e. I don't want multiple copies being created/destroyed) without exposing the
IEnumerator<T>
itself?
Update: As I mentioned in a comment below: What I want is some sort of generic Stream<T>
. I need to be able to effectively see the next item (IEnumerator.Current
-> .Peek()
) and consume it (IEnumerator<T>.MoveNext()
-> .Pop()
).
I used IEnumerator<T>
because it fit the bill interface wise. I prefer to use common BCL types when they fit, but it seemed like I was abusing this one.
So question 3) Is there a class which fits this need? Or should I just create my own Stream which lazily executes the IEnumerator<T>
internally? Then it would be entirely encapsulated. I'd like to not use many of the existing collections as they have internal storage, whereas I'd like the storage to be the IEnumerable<T>
iteslf.
OK it sounds like the consensus is that do to IEnumerator<T>
often being a ValueType
as well as not knowing a priori the state of the IEnumerator<T>
, that it is generally a bad idea to pass it around.
The best suggestion I've heard is to create my own class which gets passed around. Any other suggestions?