2008-09-19 13 views
11

随着lambda表达式(内联代码)等新功能的出现,这是否意味着我们不必再使用委托或匿名方法?在我看到的几乎所有样本中,都是使用新语法重写的。有没有一种情况下,委托语法优于匿名方法的lambda表达式?

任何我们仍然必须使用委托和lambda表达式的地方都不行?

+0

另请参见[差异之间的差异 - 匿名方法和lambda表达式](http://stackoverflow.com/questions/208381/whats-the-difference-between-anonymous-methods-c -2-0和lambda表达式)的一般差异。 – nawfal 2014-07-03 11:30:07

回答

8

lambda是匿名委托的快捷方式,但您将始终使用委托。委托指定方法签名。你可以这样做:

delegate(int i) { Console.WriteLine(i.ToString()) } 

可以

f => Console.WriteLine(f.ToString()) 
3

Lambda表达式替换只是“语法糖”,编译器将产生相应的代表为您服务。你可以使用Lutz Roeder的Reflector来调查。

+1

实际上,lambda表达式比语法糖多一点,因为它们可以编译到表达式树中并进行操作。 – 2008-09-19 23:24:35

+0

反射器现在由redgate拥有[http://www.red-gate.com/products/reflector/] – cori 2008-09-20 02:40:47

3

的Lamda的是代表只是语法糖,他们不只是为inline,可以做到以下几点:

s.Find(a => 
{ 
    if (a.StartsWith("H")) 
     return a.Equals("HI"); 
    else 
     return !a.Equals("FOO"); 
}); 

并定义事件时,或代表仍在使用,当你有很多的争论,并希望实际上强烈键入正在调用的方法。

27

是的,有些地方直接使用匿名代理和lambda表达式不起作用。

如果一个方法需要一个无类型的Delegate,那么编译器不知道该如何解析匿名委托/ lambda表达式,并且会得到编译器错误。

public static void Invoke(Delegate d) 
{ 
    d.DynamicInvoke(); 
} 

static void Main(string[] args) 
{ 
    // fails 
    Invoke(() => Console.WriteLine("Test")); 

    // works 
    Invoke(new Action(() => Console.WriteLine("Test"))); 

    Console.ReadKey(); 
} 

的代码失败的行会得到编译器错误“无法转换lambda表达式键入‘System.Delegate’,因为它不是一个委托类型”。

+0

我认为提问者询问`delegate`关键字已过时,以支持更新的基于lambda的语法。她将“匿名方法和代表”组合在一起。 – nawfal 2013-12-20 10:02:44

3

委托在C#中有两个含义。

关键字delegate可用于定义函数签名类型。这通常用于确定高阶函数的签名,即将其他函数作为参数的函数。委托的这种使用仍然相关。

关键字delegate也可用于定义内联匿名函数。在函数只是单个表达式的情况下,lambda语法是一个更简单的选择。

7

Lambda表达式不是(也不是意味着)将取代(隐藏)代表的银色子弹。它与当地的小东西是伟大的,如:

List<string> names = GetNames(); 
names.ForEach(Console.WriteLine); 
  1. 它使代码更易读这样简单的理解。
  2. 这使得代码更短对我们这样工作少;)

在另一方面,它是非常简单的滥用它们。长和/或复杂的lambda表达式都趋向于:

  1. 很难理解新开发
  2. 面向
  3. 更难读

少对象,因此“它意味着我们不'不必再使用委托或匿名方法了吗?“否 - 使用Lambda表达式来赢得时间/可读性,否则请考虑使用委托。

+0

哇!我从来没有想过这个!有没有办法做谓词,即names.Where(!string.IsNullOrEmpty)); ?我试过了,它不适合我。 哎呀!如果我删除!操作数它工作,为什么?我甚至试图把它放在括号里,但它不能完全调用它,有没有办法? 我们实际上正试图将string.IsNullOrEmpty转换为string.IsNotNullOrEmpty ... – Shimmy 2009-07-23 04:53:56

2

其中一个没有那么大较旧的delegate语法的优点是如果您不在方法体中使用它,则不需要指定参数。从msdn

有一种情况,其中一个匿名方法提供的功能 在lambda表达式未找到。匿名方法使您可以省略参数列表 。这意味着匿名方法可以将 转换为具有各种签名的委托。对于lambda表达式,这不是 。

例如,你可以这样做:

Action<int> a = delegate { }; //takes 1 argument, but not specified on the RHS 

虽然失败:

button.onClicked += delegate { Console.WriteLine("clicked"); }; 

Action<int> a = => { }; //omitted parameter, doesnt compile. 

这种技术撰写事件处理程序时,像大多来得心应手这不是的优势。最好采用总是imho的新语法。

相关问题