Can you use LINQ in an object that exposes only Add(), Remove(), Count(), Item() and GetEnumerator() from System.Collections.IEnumerator?
Not directly. You could fairly easily write a SingleShotEnumerable
though:
public sealed class SingleShotEnumerable : IEnumerable
{
private IEnumerator enumerator;
public SingleShotEnumerable(IEnumerator enumerator)
{
if (enumerator == null)
{
throw new ArgumentNullException("enumerator");
}
this.enumerator = enumerator;
}
public IEnumerator GetEnumerator()
{
if (enumerator == null)
{
throw new InvalidOperationException
("GetEnumerator can only be called once");
}
var ret = enumerator;
enumerator = null;
return ret;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
This is assuming you actually have an IEnumerator
. If you just have IEnumerator
, you could write something similar only implementing IEnumerable
, then use Cast
or OfType
to get to an IEnumerable
.
(Note: this isn't thread-safe. You could make it so with locks if you really wanted.)
You could then do:
var filtered = from person in new SingleShotEnumerable(personEnumerator)
where person.Age > 18
select person.Name;
... but you couldn't use the query twice.
How have you got into the strange situation of only having an IEnumerator
anyway? That's quite rare. See if you can design your way around that to avoid having to do something like the above, which is quite fragile.
(An alternative would be to "drain" the IEnumerator
to a List
or something similar, but that has problems dealing with large or potentially infinite sequences.)