【问题标题】:What's the difference between anonymous methods (C# 2.0) and lambda expressions (C# 3.0)? [duplicate]匿名方法 (C# 2.0) 和 lambda 表达式 (C# 3.0) 之间有什么区别? [复制]
【发布时间】:2008-10-16 12:38:33
【问题描述】:

C# 2.0 的 匿名方法 和 C# 3.0 的 lambda 表达式 有什么区别?

【问题讨论】:

    标签: c# methods expression


    【解决方案1】:

    The MSDN page on anonymous methods explains it

    在 2.0 之前的 C# 版本中,唯一的 声明委托的方法是使用 命名方法。 C# 2.0 介绍 匿名方法和在 C# 3.0 和 后来,lambda 表达式取代 匿名方法作为首选方式 编写内联代码。然而 关于匿名方法的信息 本主题也适用于 lambda 表达式。有一个案例在 匿名方法提供 在 lambda 中找不到功能 表达式。匿名方法启用 您可以省略参数列表,并且 这意味着匿名方法 可以转换为代表 各种签名。这不是 可以使用 lambda 表达式。为了 更多信息,具体关于 lambda 表达式,请参阅 Lambda 表达式(C# 编程指南)。

    And regarding lambda expressions:

    lambda 表达式是一个匿名函数,可以包含表达式和语句,并可用于创建委托或表达式树类型。 所有 lambda 表达式都使用 lambda 运算符 =>,读作“goes to”。 lambda 运算符的左侧指定输入参数(如果有),右侧保存表达式或语句块。 lambda 表达式 x => x * x 读作“x 乘以 x”。可以将这个表达式分配给一个委托类型,如下所示:

    【讨论】:

      【解决方案2】:
      1. Lambda 表达式可以转换为委托或表达式树(有一些限制);匿名方法只能转换为委托
      2. Lambda 表达式允许对参数进行类型推断:
      3. Lambda 表达式允许将主体截断为仅一个表达式(以返回值)或单个语句(在其他情况下),不带大括号。
      4. 当可以推断类型并且只有一个参数时,Lambda 表达式允许将参数列表缩短为参数名称
      5. 匿名方法允许在参数列表未在正文中使用且不会导致歧义时将其完全省略

      我相信,最后一点是匿名方法优于 lambda 的唯一好处。不过,使用无操作订阅创建类似字段的事件很有用:

      public event EventHandler Click = delegate{};
      

      【讨论】:

      • "当可以推断类型并且只有一个参数时,Lambda 表达式允许将参数列表缩短为参数名称" - 多个参数也可以,不是吗? (x,y) => {}
      • @Basic:不,那是括号中的参数名称。将其与x => x.Length 进行比较。您的示例来自第 2 点,“Lambda 表达式允许对参数进行类型推断”。
      • @JonSkeet 能否详细说明第 5 点?
      • @RichaGarg 在定义由委托变量指向的匿名方法时,如果在匿名方法的主体中未引用这些参数,则可以在定义匿名方法的主体时省略参数。查看我的代码 sn-p here 以获得更清晰的信息。 This 帖子精确地阐述了这种情况。如果我错了,乔恩请纠正我。
      • @RBT:点对点。谢谢!
      【解决方案3】:
      1. 匿名方法基本上是没有名称的函数,具有创建闭包的能力。
      2. Lambda 表达式是可转换为匿名方法和表达式树的构造,并且遵循比匿名方法更复杂的类型推断规则。

      Eric Lippert(C# 语言设计师)在他的博客中解释了或多或少细微差别的范围:

      【讨论】:

        【解决方案4】:

        首先,方便:lambda 更容易读写。

        二、表达式:lambdas可以编译成或者一个委托,或者一个表达式树(Expression<T>对于一些委托类型T,比如Func<int,bool> )。表达式树更令人兴奋,因为它是 LINQ 到进程外数据存储的关键。

        Func<int,bool> isEven = i => i % 2 == 0;
        Expression<Func<int,bool>> isEven = i => i % 2 == 0;
        

        请注意,带有语句体的 lambda 表达式只能编译为委托,而不是 Expressions:

        Action a = () => { Console.WriteLine(obj.ToString()); };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-12
          • 1970-01-01
          • 2019-03-29
          • 2012-09-27
          • 1970-01-01
          • 2011-06-23
          • 1970-01-01
          相关资源
          最近更新 更多