关于 IQueryable.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(...);
在
initialSet
上操作时,Linq-to-object 的Where
返回WhereEnumerableIterator
,因此results2< /code> 的类型为
WhereEnumerableIterator
。但是,当对someQuery
进行操作时,Where
运算符是否将通过调用someQuery.GetEnumerator
检索到的实例分配给results1
> 还是它还返回一些自定义类?如果是后者,
Where
和Select
运算符何时调用someQuery.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>
returnsWhereEnumerableIterator<T>
and thusresults2
is of typeWhereEnumerableIterator<T>
. But when operating onsomeQuery
, doesWhere<T>
operator assign toresults1
an instance retrieved by callingsomeQuery.GetEnumerator
or does it also return some custom class?If the latter, when exactly is
someQuery.GetEnumerator
called byWhere
andSelect
operators?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
results2
的类型只是Enumerable
-results2
值实际的实现类型执行时所指的恰好是WhereEnumerableIterator
,仅此而已。在
someQuery
上操作时,这取决于您用它做什么 -results1
变量的类型是IQueryable
,因此您可以对其使用更多Queryable
调用。someQuery.GetEnumerator()
可能永远被调用 - 由查询提供程序实现来确定如何准确地表示查询;它不需要像 LINQ to Objects 通常那样调用GetEnumerator
。至于
Queryable.Where
返回的对象类型 - 同样,这取决于查询提供程序的实现 - 区别在于,而知识被烘焙到Enumerable.Where
中,并且无法替换,Queryable.Where
会将调用链接到查询提供程序。The type of
results2
is justEnumerable<T>
- the type of the implementation that the value ofresults2
actually 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 theresults1
variable isIQueryable<T>
, so you can use moreQueryable
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 callGetEnumerator
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 intoEnumerable.Where
and can't be replaced,Queryable.Where
will chain the call through to the query provider.当查询被枚举时。因此得名。
这看起来是错误的。您可以使用“筛选位置”和“选择”来投影结果。你似乎把它搞反了。
When the query is enumerated. Hence comes the name.
This looks wrong. You use the Where to filter, and the Select to project the result. You appear to have it backwards.