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 =&gt; 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 表达式常用语法的主要内容,如果未能解决你的问题,请参考以下文章

Lambda表达式常用代码示例

Lambda表达式树构建(上)

java8新特性

Java8 lambda的常用方法

C++11常用知识点(下)

Python常用内置函数整理(lambda,reduce,zip,filter,map)