LINQ关键字与方法

我可以:

var something = things.Where(thing => thing.stuff == yup); var somethingelse = something.Select(thing => thing.otherstuff); 

要么

 var something = from thing in things where thing.stuff == yup select thing; var somethingelse = from thing in something select thing.otherstuff; 

显然,如果这是真实的世界,关键字版本的做法有好处:

 var somethingelse = from thing in something where thing.stuff == yup select thing.otherstuff; 

但当然你可以说你可以做到:

 var somethingelse = things.Where(thing => thing.stuff == yup) .Select(thing => thing.otherstuff); 

无论如何问题本身:使用这些变体的利弊是什么? 它们是相同的但只是不同的语法代码端吗? 如果你将两个方法版本组合在一起(例如,where / select如上所述),那么使用将两者合并为一行的关键字语法效率会降低吗?

我喜欢LINQ,我不想失去任何可以通过使用某种类型获得某些类型的效率。

查询语法将在第一遍中由编译器转换为方法语法,然后在第二遍中从该方法语法编译为IL代码。 使用查询语法编写的代码与直接在方法语法中编写的代码之间的编译代码没有区别。 (虽然并非所有方法都在查询语法中表示,但如果不部分或完全使用方法语法, 则无法编写某些查询。)

唯一的区别是编码员的个人偏好; 你发现更容易阅读或写作。

根据我的个人经验,某些类型的查询在一种语法中比另一种更容易阅读和/或写入,但这完全是一种意见问题,并且在人与人之间有所不同。 在任何给定的情况下,使用您最舒服的。

编译器将以相同的方式处理方法和LINQ语法中的代码。 使用可能取决于您自己的能力和偏好。

这个SO线程在这个问题上有一些答案。

这个SO答案警告说这一切都取决于LINQ的实现。

根据MSDN,一些查询必须用方法语法编写,但通常它们是相同的。 查询语法在编译之前转换为方法语法,因此它们最终生成相同的IL。 我个人更喜欢方法语法。 我认为一致性很重要,所以我只使用方法语法。

通过msdn;

“例如,您必须使用方法调用来表示检索与指定条件匹配的元素数量的查询。”

文章包含您正在寻找的所有信息; http://msdn.microsoft.com/en-us/library/vstudio/bb397947.aspx

使用查询语法(使用LINQ关键字)时,编译器会将代码转换为相应的LINQ方法调用,从而产生等效代码。 就查询而言,性能没有差异,每个都应该产生相同的结果。 它只会影响查询的可读性,具体取决于您更熟悉的内容。

使用查询语法的唯一“问题”(如果你这样看)是它将转换为一组特定的LINQ方法。 如果查看所有可用的LINQ方法,可以为许多标准运算符提供额外的重载,以及查询语法中没有的其他方法。 您将无法在此类查询中使用这些方法。

例如,您不能在使用查询语法的查询上使用Distinct()运算符(截至目前,希望在将来的版本和backported中)。 如果要使用它,则必须使用方法语法。 所以你必须要么混合语法(当查询变得更复杂时,这有点难看)或者只使用方法调用。

 // get all distinct user names var query1 = (from user in Users select user.Name).Distinct(); // vs. var query2 = Users .Select(user => user.Name) .Distinct(); 

如果您问我,请尽可能使用查询语法。 如果绝对必要,请使用方法调用语法。 混合风格是一种判断调用,只需要更具可读性和一致性。

您在此处调用的LINQ查询运算符用作System.Linq namesapce *中的扩展方法的语法糖,因此,就运行时效率而言,它们是相同的。 如果您愿意,您甚至可以创建自己的查询操作符,编译器将神奇地转换为方法。

如果你有兴趣了解更多,那么Jon Skeet的优秀C#in Depth的第3部分将详细介绍LINQ,包括这个问题。 另请参阅MSDN上的http://msdn.microsoft.com/en-us/library/vstudio/bb397947.aspx和http://msdn.microsoft.com/en-us/library/vstudio/bb397896.aspx 。

*您也可以提供自己实现的通常在System.Linq命名空间中公开的扩展方法,就像创建自定义LINQ运算符一样。