Something confusing about IQueryable<T>.GetEnumerator
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>returnsWhereEnumerableIterat开发者_运维知识库or<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 results2 is just Enumerable<T> - the type of the implementation that the value of results2 actually refers to at execution time happens to be WhereEnumerableIterator<T>, that's all.
When operating on someQuery, it depends what you do with it - the type of the results1 variable is IQueryable<T>, so you can use more Queryable calls 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 call GetEnumerator all 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 into Enumerable.Where and can't be replaced, Queryable.Where will chain the call through to the query provider.
If the latter, when exactly is someQuery.GetEnumerator called by Where and Select operators?
When the query is enumerated. Hence comes the name.
initialSet.Select(...).Where(...);
This looks wrong. You use the Where to filter, and the Select to project the result. You appear to have it backwards.
加载中,请稍侯......
精彩评论