Lambda 表达式常用语法
Posted
技术标签:
【中文标题】Lambda 表达式常用语法【英文标题】:Lambda expression common syntax 【发布时间】:2010-12-05 21:17:06 【问题描述】:我可以遵循任何简单的语法或规则在 C# 中构建“lambda 表达式”吗?我阅读了一些文章并理解了 lambda 表达式是什么,但如果我有通用的语法或规则会有所帮助。
【问题讨论】:
【参考方案1】:有多种表达 lambda 的方式,具体取决于具体场景 - 一些示例:
// simplest form; no types, no brackets
Func<int, int> f1 = x => 2 * x;
// optional exlicit argument brackets
Func<int, int> f2 = (x) => 2 * x;
// optional type specification when used with brackets
Func<int, int> f3 = (int x) => 2 * x;
// multiple arguments require brackets (types optional)
Func<int, int, int> f4 = (x, y) => x * y;
// multiple argument with explicit types
Func<int, int, int> f5 = (int x, int y) => x * y;
lambda 的签名必须与所使用的委托的签名相匹配(无论是显式的,如上所示,还是由上下文隐含在诸如 .Select(cust => cust.Name)
之类的内容中)
您可以通过使用一个空的表达式列表来使用 lambdas 不带 参数:
// no arguments
Func<int> f0 = () => 12;
理想情况下,右边的表达式就是这样;一个表达式。编译器可以将其转换为或者 delegate
或 Expression
树:
// expression tree
Expression<Func<int, int, int>> f6 = (x, y) => x * y;
但是;你也可以使用语句块,但这只能用作delegate
:
// braces for a statement body
Func<int, int, int> f7 = (x, y) =>
int z = x * y;
Console.WriteLine(z);
return z;
;
请注意,即使 .NET 4.0 Expression
树支持语句体,C# 4.0 编译器不会为您执行此操作,因此您仍然仅限于简单的 Expression
树,除非你用“艰难的方式”去做;请参阅my article on InfoQ 了解更多信息。
【讨论】:
【参考方案2】:从根本上说,lambda 表达式是函数指针的简写符号。更常见的是,lambda 表达式是将输入数据传播到计算结果的表达式中。在大多数情况下,您会以更常见的形式使用 lambda 表达式:
int[] numbers = new[] 1, 3, 11, 21, 9, 23, 7, 4, 18, 7, 7, 3, 21 ;
var twentyoneCount = numbers.Where(n => n == 21).Count();
var sumOfgreaterThanSeven = numbers.Sum(n => n > 7 ? n : 0);
在不太常见的形式中,lambda 表达式可以代替更繁琐的委托形式:
myButton.Click += new EventHandler(myButton_Click);
// ...
void myButton_Click(object sender, EventArgs e)
// TODO: Implement button click handler here
或者不那么常见,也不那么冗长:
myButton.Click += delegate(object sender, EventArgs e)
// TODO: Implement button click handler here
;
下面的 lambda 表达式实现了与上面两个相同的结果:
myButton.Click += (s,e) =>
// TODO: Implement button click handler here
;
后一种形式的强大之处在于其创建闭包的能力。闭包是您在函数内实现函数的地方,并在父函数范围内“关闭”参数和变量:
private void DoSomething(IList<string> input, SomeObject source)
source.OnSomeEvent += (s,e) => return input.Sum();
【讨论】:
太棒了。这正是我真正的编程世界。千感谢 jrista “从根本上说,lambda 表达式是函数指针的简写符号。”不必要。 lambda 的一个重要区别和关键特性是能够将它们视为数据(表达式树)而不是代码(匿名方法)。 ***.com/questions/793571/… @Mehrdad:没错,lambda 最初确实会变成表达式树。但是,评估表达式树的最终结果是评估委托所指向的动态方法。表达式树只是最终函数指针的中间表示。注意 .Compile() 方法,它返回一个委托:msdn.microsoft.com/en-us/library/bb345362.aspx jrista:但是没有人强迫你在表达式树上调用.Compile()
。典型的例子是 LINQ to SQL。它不会在您的表达式树上调用 compile 并且最终结果是 not 一个函数。这是一个生成的 SQL 语句。
Mehrdad:说得好。在像 L2S 这样的情况下,你是绝对正确的,它们的行为完全是表达式树。以上是关于Lambda 表达式常用语法的主要内容,如果未能解决你的问题,请参考以下文章