I'm writing code that looks similar to this:
public IEnumerable<T> Unfold<T>(this T seed)
{
while (true)
{
yield return [next (T)object in custom sequence];
}
}
Obviously, this method is never going to return. (The C# compiler silently allows this, while R# gives me the warning "Function never returns".)
Generally speaking, is it bad design to provide an enumerator that returns an infinite number of items, without supplying a way to stop enumerating?
Are there any special considerations for this scenario? Mem? Perf? Other gotchas?
If we always supply an exit condition, which are the options? E.g:
- an object of type T that represents the inclusive or exclusive boundary
- a
Predicate<T> continue
(asTakeWhile
does) - a count (as
Take
does) - ...
Should we rely on users calling Take(...)
/ TakeWhile(...)
after Unfold(...)
? (Maybe the preferred option, since it leverages existing Linq knowledge.)
Would you answer this question differently if the code was going to be published in a public API, either as-is (generic) or as a specific implementation of this pattern?