LINQ - 查询语法与方法链和lambda

Con*_*ell 55 .net c# linq lambda linq-query-syntax

当选择在其中一个LINQ扩展方法中使用LINQ查询语法或Lambda表达式时,是否有人遵守任何规则(或者您是否被迫遵守雇主的任何规则?)?这适用于任何实体,SQL,对象,任何东西.

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

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

var names = from item in collection
            select item.Name;
Run Code Online (Sandbox Code Playgroud)

也许在添加一个条件时,我发现的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;
Run Code Online (Sandbox Code Playgroud)

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

var names = collection.Select(item => item.Name)
                      .Where(name => name == "Fred");
Run Code Online (Sandbox Code Playgroud)

当然,当我们开始使用越来越多的表达式时,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;
Run Code Online (Sandbox Code Playgroud)

我发现使用查询语法也无法完成一些操作.其中一些你认为会非常简单(特别是聚合函数),但不是,你必须在最后添加一个LINQ扩展方法,imo,看起来更整洁的lambda表达式.

var names = collection.Count(item => item.Name == "Fred");

var names = (from item in collection
            where item.Name == "Fred"
            select item).Count()
Run Code Online (Sandbox Code Playgroud)

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

其他人可以添加到此吗?有没有人有他们自己的小规则或他们的公司建议/强制使用一个?

Jon*_*eet 36

要回答有关翻译的问题,查询表达式将始终根据C#4规范7.16(或C#3规范中的等效规则)的规则进行翻译.在您询问有关Name属性的问题的示例中,这不是查询表达式转换的问题 - 它是SelectWhere它们作为参数使用委托或表达式树的方法.有时在过滤之前进行投影是有意义的,有时则不然.

至于小规则,我只有一个:使用对于查询中最可读的方式.因此,如果查询更改并且"哪个表单更具可读性"同时更改,请更改使用的语法.

如果您打算使用LINQ,您应该对这两种语法感到满意,至少要阅读.

倾向于发现具有多个范围变量的查询(例如via SelectManyJoin,或者一个let子句)最终使用查询表达式更具可读性 - 但这远不是一个硬性规则.

  • 查询语法也不提供所有运算符. (3认同)
  • @ConnellWatkins:我认为当你只对*应用过滤器感兴趣时,"从哪里选择"的丑陋远比lambda的丑陋要大得多 - 如果他们想要一个不过载的话,他们会做什么呢?是否支持?我已经解决了"Just out of interest"这个问题 - 编译器遵循语言规范,就这么简单. (3认同)
  • 像往常一样,乔恩打败了我.我会说同样的话:这取决于.首选对于给定查询更易于维护的语法.至于不支持的方法,我将指出VB确实具有更多查询表达式的语言支持(Skip,Take,Distinct,Aggregate).我经常看到的一个例子我将添加:对于一个投影单个项目的简单过滤器,我更喜欢`items.First(i => i.Prop == value)`over`(来自i的项目,其中i.Prop = =值选择i).First()` (2认同)
  • 当您开始将扩展方法链接在一起(尤其是您自己编写的扩展方法)时,事情看起来比组合两种语法要好得多。 (2认同)
  • @ConnellWatkins:哦有很多可能性 - 请参阅http://morelinq.googlecode.com :) (2认同)
  • 除了“join”之外,我在任何地方都使用方法链。 (2认同)