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(...);
在initialSet
上操作时,Linq-to-object的Where<T>
会返回WhereEnumerableIterator<T>
,因此results2
的类型为WhereEnumerableIterator<T>
。但是当在someQuery
上运行时,Where<T>
运算符是否通过调用results1
将someQuery.GetEnumerator
检索到的实例分配给someQuery.GetEnumerator
,还是返回一些自定义类?
如果是后者,Where
和Select
运营商究竟何时调用{{1}}?
答案 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}}会将调用链接到查询提供程序。