So what you are trying to do is to have an implementation of IEnumerable<T>
which has a singleton IEnumerator<T>
? Why not implement that explicitly, instead of using undocumented (?) behaviour of List<T>
's iterator?
Simply create a class that consumes a IEnumerable<T>
, takes its iterator and wraps it in an implementation of IEnumerator<T>
that has a dysfunctional Reset
method. IEnumerator<T>.GetEnumerator()
can then return the instance to that same iterator instead of creating a new one for each call. It could look something like this:
public class OnlyOnceIterator<T> : IEnumerable<T>, IEnumerator<T> {
private readonly IEnumerator<T> enumerator;
internal OnlyOnceIterator(IEnumerable<T> sequence) {
enumerator = sequence.GetEnumerator();
}
public T Current => enumerator.Current;
object IEnumerator.Current => enumerator.Current;
public void Dispose() {
enumerator.Dispose();
}
public IEnumerator<T> GetEnumerator() => this;
public bool MoveNext() {
return enumerator.MoveNext();
}
public void Reset() {
return;
}
IEnumerator IEnumerable.GetEnumerator() => this;
}
This could then be used in an extension method:
public static OnlyOnceIterator<T> ToOnlyOnceIterator<T>(this IEnumerable<T> sequence) {
if (sequence == null) {
throw new System.ArgumentNullException(nameof(sequence));
}
return new OnlyOnceIterator<T>(sequence);
}
Additionally, I would prefer a more specific return type than IEnumerable<T>
, since the returned behaviour is significantly different to what any user might expect from IEnumerable<T>
. Consider creating a new interface that inherits from IEnumerable<T>
with a more descriptive name. Through inheritance, Linq will still be able to be used, and you can create methods that only accept this specific interface, (compare this to IOrderedEnumerable<T>
).
List<T>
iterator here which isIDisposable
. I bet that this concreteDispose()
implementation does nothing, so it should be safe to do not invoke it. \$\endgroup\$x.Take(3); x.Any(i => i == 1);
return false forAny()
, and many otherIEnumerable<T>
linq-apis will behave unexpectedly on this kind ofIEnumerable<T>
. IMO you're mixing two distinct concepts that should be kept distinct. \$\endgroup\$