LINQ – 查询语法与方法链&lambda

有没有人坚持任何规则(或者你是否坚持你的雇主的任何规则?)当select使用LINQ查询语法或一个LINQ扩展方法内的Lambdaexpression式? 这适用于任何实体,SQL,对象,任何东西。

在我们的工作场所,我的老板根本就不喜欢lambda,他会使用查询语法来处理任何事情,在某些情况下,我发现它的可读性较差。

var names = collection.Select(item => item.Name); var names = from item in collection select item.Name; 

也许当添加一个条件,我觉得Lambda有点混乱,在哪里

 var names = collection.Where(item => item.Name == "Fred") .Select(item => item.Name); var names = from item in collection where item.Name == "Fred" select item.Name; 

出于兴趣:编译器如何处理这个? 有谁知道上面的LINQ查询将如何编译成lambda? 是否会为每个元素调用Name属性? 我们可以这样做,并可能提高性能? 这是否意味着lambda在性能方面稍微有点可控性?

 var names = collection.Select(item => item.Name) .Where(name => name == "Fred"); 

当然,当我们开始使用越来越多的expression式时,lambda会变得杂乱,我会开始在这里使用查询语法。

 var names = collection.Where(item => item.Name == "Fred") .OrderBy(item => item.Age) .Select(item => item.Name); var names = from item in collection where item.Name == "Fred" order by item.Age select item.Name; 

还有一些我发现不能用查询语法完成的事情。 其中一些你认为会非常简单(特别是聚合函数),但不是,你必须添加一个LINQ扩展方法到最后,这个imo,看起来更加整齐的一个lambdaexpression式。

 var names = collection.Count(item => item.Name == "Fred"); var names = (from item in collection where item.Name == "Fred" select item).Count() 

即使对于一些简单的lambda链, ReSharperbuild议我将它们转换为LINQ查询。

任何人都可以添加到这个? 有没有人有自己的小规则或他们的公司build议/强制使用?

要回答您的翻译问题,查询expression式将总是基于C#4规范(或C#3规范中的等效规则)的规则进行翻译。 在你提出有关Name属性的问题的例子中,这不是查询expression式转换的问题 – 这是SelectWhere方法用它们作为参数的委托或expression式树所做的事情。 有时在过滤之前进行投影是有意义的,有时候不是。

至于小规则,我只有一个:使用哪种方式对于有问题的查询来说最具可读性。 因此,如果查询更改并且“哪个表单更具可读性”同时发生更改,请更改所用的语法。

如果你打算使用LINQ,你应该对任何语法感到满意,至less要阅读。

倾向于发现使用多个范围variables(例如,通过SelectManyJoin ,或者一个let子句)的查询最终可以使用查询expression式更具可读性 – 但是这远非一条硬性规定。