当使用LINQ时,是否必须使用lambda表达式,或lambda表达式是否可选?
在lambda表达式中,始终使用符号=>
。这是什么意思?
customers.Where(c => c.City == "London");
这里使用了c =>
但是为什么?
使用c =>
有什么意义。请详细讨论因为我不懂lambda。
答案 0 :(得分:11)
不,你没有拥有来使用lambda表达式。例如,您的Where
示例可以写为:
private static bool IsLondon(Customer customer)
{
return customer.City == "London";
}
...
var londoners = customers.Where(IsLondon);
当然,这是假设对象的LINQ。对于LINQ to SQL等,您需要构建表达式树。
至于为什么“=>”总是在lambda表达式中使用,这只是因为这就是运算符的编写方式 - 就像问为什么“+”用于添加一样。
lambda表达式“c => ...”实际上为lambda表达式提供了一个名为c
的参数 ...在这种情况下,泛型类型推断提供了 c
的类型。正文提供了要执行的操作或某些计算以根据c
返回值。
lambda表达式的完整描述超出了本答案的范围。然而,作为my book的公然插件,它们在深度C#的第9章中有详细介绍。
答案 1 :(得分:7)
lambda表达式
c => c.City == "London"
是
之类的简写bool IsCustomerInLondon(Customer c)
{
return (c.City == "London");
}
这只是编写一个返回值的简单函数的一种非常简洁的方法。它被称为“匿名函数”,因为它从未被赋予名称或正式定义(参数类型和返回类型是从上下文中推断出来的。)
(实际上,它不是只是的简写; lambda表达式与其他一些名为closures的构造相关,这些构造非常酷且功能强大。)
答案 2 :(得分:4)
将lambdas视为函数的匿名者。 我将尝试用以下代码解释它。
public bool IsLondon(Customer customer)
{
return customer.City == "London";
}
现在我们删除函数名称并删除大括号:
public bool Customer customer
return customer.City == "London";
我们不需要返回类型,因为编译器能够从表达式中推断出类型:
customer.City == "London";
编译器以相同的方式了解输入类型,因此我们不需要指定它。
基本上,我们留下的是
customer
return customer.City == "London";
c#中的lambda语法基本上是:
(parameter list) => "expression"
你也可以编写“多行”表达式,但是你必须用花括号括起你的代码。此外,您需要像往常一样使用“return”语句。
答案 3 :(得分:1)
Lambda和linq是完全分开的。你可以使用一个而不使用另一个(linq的部分依赖于lambda表达式,但我们希望保持简单:-))
lambda表达式是匿名的 可以包含表达式的函数 和陈述,可以用来 创建委托或表达式树 类型。
这是来自MSDN。 (http://msdn.microsoft.com/en-us/library/bb397687.aspx)
要使它变短(它要复杂得多),你可以使用lambda表达式来创建一个本地函数。你在=>之前放的是什么(在你的例子中,c)将是函数的参数。返回类型由C#编译器“发现”。
c => c.City == "London"
几乎等同于:
delegate (TheObjectTypeOfC c) {
return c.City == London
};
(区别在于一些lambda表达式是委托和表达式,但请忽略它,一段时间不需要它)
如果/当编译器无法推断参数的类型时,您可以强制它们:(MyObject p) => p.SomeProperty != null
。在这里,您告诉编译器p是一个参数。
在这里,我向你展示了所谓的“表达lambdas”,你甚至可以做“声明lambdas”:
p => {
for (int i = 0; i < 10; i++) {
if (p.SomeProperty == 0) {
return true;
}
}
return false;
}
(我不会告诉你表达式lambdas和语句lambdas之间的“幕后”差异。如果你想了解它们,请阅读我之前指出的msdn页面)
答案 4 :(得分:1)
在你给出的例子中,想象Linq循环所有客户, 和c只是对可枚举项中每个项的引用:
var result = new List<Customer>();
foreach(var c in customers)
{
if (c.City == "London")
result.Add(c);
}
return result;
它是一个与其他变量一样的变量,它不必是一个命名的变量, 但这只是某种约定。
答案 5 :(得分:1)
你不需要在Lİnq上使用lambda表达式来实现sql或Entities;这是代码的另一种方式;
你编码:
customers.Where(c => c.City == "London");
另一种方式;
var query = from cs in customers
where cs.City == "London"
select cs;
这是另一种方式。这取决于你。
答案 6 :(得分:1)
不,没有必要。
我们有两种方法来编写LINQ查询。
一种是查询方法,另一种是构建方法。在构建器方法的情况下,您只需要放置lambda表达式。 例如,如果我们想要从一些学生对象中找到那些标记多于70的学生。 但我们可以使用以下语法在LINQ中执行此操作
var data = from p in stdList
where p.marks > 70
select p;
或 var data = stdList.Where(p =&gt; p.marks&gt; 70);
后面的方法是构建器方法,在Where函数中,我们传递lambda表达式。
Lambda表达式只是简单的做事,你可以随时使用LINQ查询但是如果你想避免使用简单条件的整个查询语法,你可以在lambda表达式中使用LINQ构建器方法(要求lambda表达式) ,你总是定义一些别名,然后执行你的操作。
至于=&gt;运算符,它就像赋值运算符一样工作。 例如:
(p) => p.Gender == “F”
It means “All persons p, such that person’s Gender is F”
在一些文献中,这被称为“谓词”。另一个文献术语是“投影”
(p) => p.Gender ? “F” : “Female”
“Each person p becomes string “Female” if Gender is “F””
这是投影,它使用三元运算符。 虽然我用非常基本的例子解释,但我希望这会对你有所帮助。 。 。 :)