[英]How does Linq projection work between Extention Method and query expression
Fiddling around with Linq, and to my surprise I meet the following: 摆弄Linq,令我惊讶的是我遇到了以下情况:
var words = new List<string>() {"seven", "ten", "one" ,"five"};
var test1 = words.OrderBy(w => w.Length);
var test2 = words.OrderBy(w => w.Lenght).Select(w => w);
var test3 = from w in words
orderby w.Length
select w;
And VS debug tells me VS调试告诉我
test1: System.Linq.IOrderedEnumerable<string>
test2: System.Collections.Generic.IEnumerable<string>
test3: System.Linq.IOrderedEnumerable<string>
I was expecting same type for test2
and test3
, and oh boy!, the compiler, or whatever it is, thinks otherwise. 我期待
test2
和test3
相同类型,哦男孩!,编译器,或者其他什么,不这么认为。
test2
instead of test1
as long as I'm projecting to the same type? test2
而不是test1
,只要我投射到同一类型? ie Select(w => w)
Select(w => w)
The compiler omits the call to Select
when there is no real transformation in the select
clause of the query expression. 当查询表达式的
select
子句中没有实际转换时,编译器会忽略对Select
的调用。 That's why the queries in test1
and test3
are equivalent. 这就是为什么
test1
和test3
中的查询是等价的。
My answer is based on this post from Jon Skeet's blog (read the Query expressions paragraph): LINQ to Objects 我的回答是基于Jon Skeet博客的这篇文章(阅读查询表达式段落): LINQ to Objects
var result = from x in source
where x < 4
select x;
(...) we're not actually performing a real transformation.
(...)我们实际上并没有进行真正的转型。 In that case – and so long as there's something else in the query, in this case our "where" clause – the compiler effectively omits the "select" clause (...)
在那种情况下 - 只要查询中还有其他内容,在本例中我们的“where”子句 - 编译器有效地省略了“select”子句(...)
Regarding the second part of your question, when you invoke Select
at the end, you'll get an IEnumerable<T>
, because that's what Select
returns. 关于你问题的第二部分,当你在最后调用
Select
时,你会得到一个IEnumerable<T>
,因为那就是Select
返回的。 IOrderedEnumerable<T>
extends IEnumerable<T>
, so by making a projection at the end you lose the ability to use members of the IOrderedEnumerable<T>
interface. IOrderedEnumerable<T>
扩展IEnumerable<T>
,因此通过在末尾进行投影,您将失去使用IOrderedEnumerable<T>
接口成员的能力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.