关于IQueryable <t> .GetEnumerator </t>的一些令人困惑的事情

时间:2011-09-27 18:31:10

标签: linq iqueryable

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. initialSet上操作时,Linq-to-object的Where<T>会返回WhereEnumerableIterator<T>,因此results2的类型为WhereEnumerableIterator<T>。但是当在someQuery上运行时,Where<T>运算符是否通过调用results1someQuery.GetEnumerator检索到的实例分配给someQuery.GetEnumerator,还是返回一些自定义类?

  2. 如果是后者,WhereSelect运营商究竟何时调用{{1}}?

2 个答案:

答案 0 :(得分:2)

  

如果是后者,那么究竟是someQuery.GetEnumerator调用的   Where和Select运算符?

枚举查询时。因此得名。

initialSet.Select(...).Where(...);

这看起来不错。您可以使用“过滤位置”和“选择”来投影结果。你看起来倒退了。

答案 1 :(得分:2)

results2的类型只是Enumerable<T> - {em>实现的类型,results2在执行时实际引用的值恰好是{ {1}},就是这样。

WhereEnumerableIterator<T>上运行时,取决于您使用它做什么 - someQuery变量的类型为results1,因此您可以使用更多{ {1}}要求它。

IQueryable<T>可能从不被调用 - 由查询提供程序实现来确定如何表示查询;它不需要像LINQ to Objects那样在链上一直调用Queryable

至于someQuery.GetEnumerator()返回的对象类型 - 再次由查询提供程序实现 - 不同之处在于知识被烘焙到GetEnumerator并且无法替换,{ {1}}会将调用链接到查询提供程序。