public class Query<T> : IQueryable<T> ...
{
...
public IEnumerator<T> GetEnumerator()
{
return((IEnumerable<T>)this.provider.Execute(this.expression)).GetEnumerator();
}
}
Query<string> someQuery = new Query<string>();
var results1 = someQuery.Select(...).Where(...);
string[] initialSet = { };
var results2 = initialSet.Select(...).Where(...);
-
When operating on
initialSet, Linq-to-object’sWhere<T>returnsWhereEnumerableIterator<T>and thusresults2is of typeWhereEnumerableIterator<T>. But when operating onsomeQuery, doesWhere<T>operator assign toresults1an instance retrieved by callingsomeQuery.GetEnumeratoror does it also return some custom class? -
If the latter, when exactly is
someQuery.GetEnumeratorcalled byWhereandSelectoperators?
The type of
results2is justEnumerable<T>– the type of the implementation that the value ofresults2actually refers to at execution time happens to beWhereEnumerableIterator<T>, that’s all.When operating on
someQuery, it depends what you do with it – the type of theresults1variable isIQueryable<T>, so you can use moreQueryablecalls on it.someQuery.GetEnumerator()may never be called – it’s up to the query provider implementation to work out exactly how to represent the query; it doesn’t need to callGetEnumeratorall the way up the chain like LINQ to Objects typically does.As for the type of object returned by
Queryable.Where– again, that’s up to the query provider implementation – the difference is that whereas the knowledge is baked intoEnumerable.Whereand can’t be replaced,Queryable.Wherewill chain the call through to the query provider.