C# Linq投影如何在扩展方法和查询表达式之间工作
与Linq闲逛,令我惊讶的是,我遇到了以下情况:C# Linq投影如何在扩展方法和查询表达式之间工作,c#,linq,C#,Linq,与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 orderb
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;
var words=newlist(){“七”、“十”、“一”、“五”};
var test1=words.OrderBy(w=>w.Length);
var test2=words.OrderBy(w=>w.Lenght)。选择(w=>w);
var test3=来自w(大写)
按w.长度排序
选择w;
VS调试告诉我
test1: System.Linq.IOrderedEnumerable<string>
test2: System.Collections.Generic.IEnumerable<string>
test3: System.Linq.IOrderedEnumerable<string>
test1:System.Linq.IOrderedEnumerable
测试2:System.Collections.Generic.IEnumerable
测试3:System.Linq.IOrderedEnumerable
我希望test2
和test3
使用相同的类型,哦,天哪!,编译器,或者不管它是什么,都不这么认为
test2
而不是test1
,只要我投影到相同的类型?i、 e.选择(w=>w)
当查询表达式的
Select
子句中没有真正的转换时,编译器将省略对Select
的调用。这就是为什么test1
和test3
中的查询是等价的
我的答案基于Jon Skeet博客上的这篇文章(阅读查询表达式段落):
var result=源中的x
其中x<4
选择x;
(…)我们实际上并没有执行真正的转换。在这种情况下,只要查询中还有其他内容,在本例中是我们的“where”子句,编译器就会有效地省略“select”子句(…)
关于问题的第二部分,当您在最后调用
Select
时,您将得到一个IEnumerable
,因为这就是Select
返回的结果IOrderedEnumerable
扩展了IEnumerable
,因此通过在末尾进行投影,您将失去使用IOrderedEnumerable
接口成员的能力。因此不需要在test2中选择?但让我思考的是为什么编译器会推断出不同的类型。我想这一定是有原因的。此外,编译器似乎强制您将Select子句放入查询表达式中,无论是否存在真正的转换。@rm它是一种不同的类型,因为OrderBy
返回一个iorderenumerable
,而Select
返回一个IEnumerable
IOrderedEnumerable
扩展了IEnumerable
,因此,通过在末尾进行投影,您将无法使用IOrderedEnumerable
接口的成员。是的,你每次都必须写select
子句。哦,是的。我懂了。您的评论完成了答案。谢谢大家!@rm我会把这个添加到答案中。
var result = from x in source
where x < 4
select x;