There are lots of Linq algorithms that only need to do one pass through the input e.g. Select.
Yet all the Linq extension methods sit on IEnumerable rather than IEnumerator
var e = new[] { 1, 2, 3, 4, 5 }.GetEnumerator();
e.Select(x => x * x); // Doesn't work
This means you can't use Linq in any situation where you are reading from an "already opened" stream.
This scenario is happening a lot for a project I am currently working on - I want to return an IEnumerator whose IDispose method will close the stream, and have all the downstream Linq code operate on this.
In short, I have an "already opened" stream of results which I can convert into an appropriately disposable IEnumerator - but unfortunately all of the downstream code requires an IEnumerable rather than an IEnumerator, even though it's only going to do one "pass".
i.e. I'm wanting to "implement" this return type on a variety of different sources (CSV files, IDataReaders, etc.):
class TabularStream
{
Column[] Columns;
IEnumerator<object[]> RowStream;
}
In order to get the "Columns" I have to have already opened the CSV file, initiated the SQL query, or whatever. I can then return an "IEnumerator" whose Dispose method closes the resource - but all of the Linq operations require an IEnumerable.
The best workaround I know of is to implement an IEnumerable whose GetEnumerator() method returns the one-and-only IEnumerator and throws an error if something tries to do a GetEnumerator() call twice.
Does this all sound OK or is there a much better way for me to implement "TabularStream" in a way that's easy to use from Linq?