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

47

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

4个回答

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

我认为,最后一点是匿名方法比Lambda表达式更具优势的唯一方面。它可用于创建一个无操作订阅的类似字段的事件:

public event EventHandler Click = delegate{};

Lambda表达式允许在类型可以被推断并且只有一个参数时将参数列表缩短为仅参数名称。多个参数也可以,对吧?(x,y) => {} - Basic
1
@Basic:不,那是括号中的参数名称。将其与 x => x.Length 进行比较。你的例子来自第2点,“Lambda表达式允许对参数进行类型推断”。 - Jon Skeet
1
@JonSkeet,您能否详细说明第五点? - Richa Garg
1
@RichaGarg 在定义被委托变量指向的匿名方法时,如果这些参数在匿名方法的主体中没有被引用,那么在定义匿名方法的主体时可以省略这些参数。请查看我的代码片段此处以获得更多的清晰度。这篇文章精确地阐述了这种情况。如果我说错了,请纠正我,Jon。 - RBT
@RBT:非常准确。谢谢! - Jon Skeet

31

MSDN关于匿名方法的页面详细解释了它

在C# 2.0之前的版本中,声明委托的唯一方式是使用命名方法。C# 2.0引入了匿名方法,在C# 3.0及更高版本中,Lambda表达式取代匿名方法成为编写内联代码的首选方式。但是,在本主题中关于匿名方法的信息同样适用于Lambda表达式。有一种情况下匿名方法提供了Lambda表达式没有的功能。匿名方法使您可以省略参数列表,这意味着匿名方法可以转换为具有各种签名的委托。Lambda表达式无法做到这一点。有关Lambda表达式的更多信息,请参阅Lambda表达式 (C# 编程指南)。

关于Lambda表达式:

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


27
  1. 匿名方法本质上是没有名称的函数,具有创建闭包的能力。
  2. Lambda表达式是可转换为匿名方法和表达式树的构造,并遵循比匿名方法更复杂的类型推断规则。

Eric Lippert(C# 语言设计师)在他的博客中解释了这些相对微妙的差异:


14

首先,便利性:lambda表达式更易于阅读和编写。

其次,表达式:lambda表达式可以编译为委托或表达式树(例如,对于某些委托类型T,如Func<int,bool>,可以编译为Expression<T>)。表达式树更加令人兴奋,因为它是LINQ到外部数据存储的关键。

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

请注意,使用语句体的 lambda 表达式只能编译为委托,而非表达式。
Action a = () => { Console.WriteLine(obj.ToString()); };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接