开发者

Something confusing about IQueryable<T>.GetEnumerator

开发者 https://www.devze.com 2023-04-07 20:49 出处:网络
public class Query<T> : IQueryable<T> ... { ... public IEnumerator<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(...);
  1. When operating on initialSet, Linq-to-object's Where<T> returns WhereEnumerableIterat开发者_运维知识库or<T> and thus results2 is of type WhereEnumerableIterator<T>. But when operating on someQuery, does Where<T> operator assign to results1 an instance retrieved by calling someQuery.GetEnumerator or does it also return some custom class?

  2. If the latter, when exactly is someQuery.GetEnumerator called by Where and Select operators?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号