C# 扩展方法语法与查询语法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/279701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extension methods syntax vs query syntax
提问by Armstrongest
I'm trying to get a handle on if there's a good time to use standard linq keywords or linq extension methods with lambda expressions. They seems to do the same thing, just are written differently. Is it purely a matter of style?
我正在尝试了解是否有时间将标准 linq 关键字或 linq 扩展方法与 lambda 表达式一起使用。他们似乎做同样的事情,只是写法不同。这纯粹是风格问题吗?
var query = from p in Products
where p.Name.Contains("foo")
orderby c.Name
select p;
// or with extension methods:
var query = Products
.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name);
They're very similar with the second example being a bit more terse, but perhaps less expressive if you don't know what the => is doing.
它们非常相似,第二个示例更简洁一些,但如果您不知道 => 正在做什么,则表达能力可能会降低。
Other than writing terse code, are there other advantages to using the extension methods as opposed to the LINQ syntax?
除了编写简洁的代码之外,与 LINQ 语法相比,使用扩展方法还有其他优势吗?
采纳答案by Programmin Tool
Honestly, sometimes it can be situational once you start using Funcs and Actions. Say you are using these three funcs:
老实说,一旦您开始使用 Funcs 和 Actions,有时可能会因情况而异。假设您正在使用这三个函数:
Func<DataClasses.User, String> userName = user => user.UserName;
Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;
As you can see the first one replaces the lamdba expression to get the user name, the second replaces a lamdba expression used to check if the ID is lower than 10, and let's face it, the third should be pretty easy to understand now.
如您所见,第一个替换 lamdba 表达式以获取用户名,第二个替换用于检查 ID 是否小于 10 的 lamdba 表达式,让我们面对现实,第三个现在应该很容易理解。
NOTE: This is a silly example but it works.
注意:这是一个愚蠢的例子,但它有效。
var userList =
from user in userList
where userIDOverTen(user)
select userName;
Versus
相对
var otherList =
userList
.Where(IDIsBelowNumber)
.Select(userName)
In this example, the second is a little less verbose since the extension method can make full use of the Func, but he Linq expression can't since it is look just for a Boolean rather than a Func that returns boolean. However, this is where it might be better to use the expression language. Say you already had a method that takes in more than just a user:
在这个例子中,第二个不那么冗长,因为扩展方法可以充分利用 Func,但 Linq 表达式不能,因为它只是寻找一个 Boolean 而不是一个返回布尔值的 Func。但是,这就是使用表达式语言可能更好的地方。假设你已经有一个方法,它不仅仅是一个用户:
private Boolean IDIsBelowNumber(DataClasses.User user,
Int32 someNumber, Boolean doSomething)
{
return user.UserID < someNumber;
}
Note: doSomething is just there because of the where extension method being ok with a method that takes in a user and integer and returns boolean. Kind of annoying for this example.
注意:doSomething 就在那里,因为 where 扩展方法可以接受用户和整数并返回布尔值的方法。这个例子有点烦人。
Now if you look at the Linq query:
现在,如果您查看 Linq 查询:
var completeList =
from user in userList
where IDIsBelowNumber(user, 10, true)
select userName;
You're good for it. Now the Extension Method:
你对它有好处。现在扩展方法:
var otherList =
userList
.Where(IDIsBelowNumber????)
.Select(userName)
Without a lambda expression, I really can't call that method. So now what I have to do is create a method that creates a Func based off the original method call.
没有 lambda 表达式,我真的无法调用该方法。所以现在我要做的是创建一个基于原始方法调用创建 Func 的方法。
private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
{
return user => IDIsBelowNumber(user, number, true);
}
And then plug it in:
然后插入:
var otherList =
userList
.Where(IDIsBelowNumberFunc(10))
.Select(userName)
So you can see, sometimes it may just be easier to use the query approach at times.
所以你可以看到,有时有时使用查询方法可能更容易。
回答by Mark Brackett
They compile the same, and are equivalent. Personally, I prefer the lambda (extension) methods for most things, only using the statements (standard) if I'm doing LINQ to SQL or otherwise trying to emulate SQL. I find that the lambda methods flow better with code, whereas the statements are visually distracting.
它们编译相同,并且是等效的。就我个人而言,对于大多数事情,我更喜欢 lambda(扩展)方法,仅在我执行 LINQ to SQL 或以其他方式尝试模拟 SQL 时才使用语句(标准)。我发现 lambda 方法与代码一起流动得更好,而语句在视觉上会分散注意力。
回答by Nathan W
One advantage to using LINQ extension methods (method-based queries) is that you can define custom extension methods and it will still read fine.
使用 LINQ 扩展方法(基于方法的查询)的一个优点是您可以定义自定义扩展方法并且它仍然可以正常读取。
On the other hand, when using a LINQ query expression, the custom extension method is not in the keywords list. It will look a bit strange mixed with the other keywords.
另一方面,当使用 LINQ查询表达式时,自定义扩展方法不在关键字列表中。与其他关键字混合看起来会有点奇怪。
Example
例子
I am using a custom extension method called Into
which just takes a string:
我正在使用一个名为的自定义扩展方法Into
,它只需要一个字符串:
Example with query
查询示例
var query = (from p in Products
where p.Name.Contains("foo")
orderby c.Name
select p).Into("MyTable");
Example with extension methods
扩展方法示例
var query = Products
.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name)
.Into("MyTable");
In my opinion the latter, using a method-based query, reads better when you have custom extension methods.
在我看来,后者使用基于方法的查询,当您拥有自定义扩展方法时,阅读效果会更好。
回答by Eric Minkes
I prefer the extension method syntax when I use Linq methods that have no query syntax equivalent, such as FirstOrDefault() or others like that.
当我使用没有等效查询语法的 Linq 方法(例如 FirstOrDefault() 或其他类似方法)时,我更喜欢扩展方法语法。
回答by Rodi
I think it's a good idea not to use them together and choose one and stick with it.
我认为最好不要将它们一起使用并选择一个并坚持使用。
Mostly it's personal taste, but in the query syntax (Comprehension method) not all operators are available as was said before.
主要是个人喜好,但在查询语法(理解方法)中,并非所有运算符都可用,如前所述。
I find the Extension Methods syntax more in line with the rest of my code. I do my SQL in SQL. It's also very easy to build your expression just by adding everything on top of eachother with the extension methods.
我发现扩展方法语法更符合我的其余代码。我在 SQL 中执行我的 SQL。只需使用扩展方法在彼此之上添加所有内容,即可轻松构建表达式。
Just my two cents.
只有我的两分钱。
As I cannot make comments yet I want to make one here to the answer of Programming Tool: Why make a whole new method for the last example?? Can't you just use:
由于我还不能发表评论,我想在这里对编程工具的答案做一个评论:为什么要为最后一个示例创建一个全新的方法?你不能只使用:
.Where(user => IDIsBelowNumber(user, 10, true))
.Where(user => IDIsBelowNumber(user, 10, true))
回答by nawfal
I like to use the query syntax when its really a query, ie a lazy expression which evaluates on demand.
我喜欢在查询时使用查询语法,即按需计算的惰性表达式。
A method that looks like regular method calls (method syntax or the lambda syntax) doesn't look lazy enough, so I use that as a convention. For eg,
看起来像常规方法调用(方法语法或 lambda 语法)的方法看起来不够懒惰,因此我将其用作约定。例如,
var query = from p in Products
where p.Name.Contains("foo")
orderby p.Name
select p;
var result = query.ToList(); //extension method syntax
If it's a not a query, I like the fluent style which looks to me consistent with other eagerly executing calls.
如果不是查询,我喜欢流利的风格,它在我看来与其他急切执行的调用一致。
var nonQuery = Products.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name)
.ToList();
It helps me to differentiate the two styles of calls better. Of course there are situations where you will be forced to use method syntax anyway, so my convention is not very compelling enough.
它帮助我更好地区分这两种调用方式。当然,在某些情况下,无论如何您都将被迫使用方法语法,因此我的约定不够引人注目。
回答by bradley4
One advantage of extension methods/lynda expressions is the additional operators that is offered like Skip and Take. For example, if you are creating a pagination method, being able to skip the first 10 records and take the next 10 is easy to implement.
扩展方法/lynda 表达式的优点之一是提供了额外的运算符,如 Skip 和 Take。例如,如果您正在创建分页方法,则能够跳过前 10 条记录并采用接下来的 10 条记录很容易实现。