【问题标题】:Lambda expression common syntaxLambda 表达式常用语法
【发布时间】:2010-12-05 21:17:06
【问题描述】:

我可以遵循任何简单的语法或规则在 C# 中构建“lambda 表达式”吗?我阅读了一些文章并理解了 lambda 表达式是什么,但如果我有通用的语法或规则会有所帮助。

【问题讨论】:

    标签: c# 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 的一个重要区别和关键特性是能够将它们视为数据(表达式树)而不是代码(匿名方法)。 stackoverflow.com/questions/793571/…
      • @Mehrdad:没错,lambda 最初确实会变成表达式树。但是,评估表达式树的最终结果是评估委托所指向的动态方法。表达式树只是最终函数指针的中间表示。注意 .Compile() 方法,它返回一个委托:msdn.microsoft.com/en-us/library/bb345362.aspx
      • jrista:但是没有人强迫你在表达式树上调用.Compile()。典型的例子是 LINQ to SQL。它不会在您的表达式树上调用 compile 并且最终结果是 not 一个函数。这是一个生成的 SQL 语句。
      • Mehrdad:说得好。在像 L2S 这样的情况下,你是绝对正确的,它们的行为完全是表达式树。
      猜你喜欢
      • 2011-07-12
      • 2011-07-04
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多