12

With the advent of new features like lambda expressions (inline code), does it mean we dont have to use delegates or anonymous methods anymore? In almost all the samples I have seen, it is for rewriting using the new syntax.

Any place where we still have to use delegates and lambda expressions won't work?

4

7 回答 7

27

是的,有些地方直接使用匿名委托和 lambda 表达式是行不通的。

如果方法采用无类型委托,则编译器不知道将匿名委托/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',因为它不是委托类型”。

于 2008-09-20T00:00:29.180 回答
8

lambda is shortcut for anonymous delegate, but you will always be using delegates. the delegate specifies the methods signature. you can just do this:

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

can be replaced with

f => Console.WriteLine(f.ToString())
于 2008-09-19T23:20:11.277 回答
7

Lambda 表达式不是(也不打算成为)替代(隐藏)委托的灵丹妙药。非常适合当地的小事,例如:

List<string> names = GetNames();
names.ForEach(Console.WriteLine);
  1. 它使代码更具可读性,因此易于理解。
  2. 它使代码更短,从而减少了我们的工作量;)

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

  1. 新开发者难以理解
  2. 较少面向对象
  3. 更难阅读

那么“这是否意味着我们不必再使用委托或匿名方法了?” 不——在你赢得时间/可读性的地方使用 Lambda 表达式,否则考虑使用委托。

于 2008-09-29T15:51:20.027 回答
4

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

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

delegate关键字还可用于定义内联匿名函数。在函数只是单个表达式的情况下,lambda 语法是一种更简单的替代方案。

于 2008-09-27T22:33:07.787 回答
3

Lambda 表达式只是“语法糖”,编译器将为您生成适当的委托。您可以使用 Lutz Roeder 的反射器对此进行调查。

于 2008-09-19T23:22:13.970 回答
3

lamda 只是代表的语法糖,它们不仅仅是内联的,您可以执行以下操作:

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

在定义事件时,或者当您有很多参数并且想要实际强类型被调用的方法时,仍然会使用委托。

于 2008-09-19T23:27:20.773 回答
3

旧语法的一个不太大delegate的优势是,如果您不在方法主体中使用它,则无需指定参数。来自msdn

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

例如,您可以这样做:

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

虽然这失败了:

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

这种技术在编写事件处理程序时非常方便,例如:

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

这不是一个强大的优势。最好总是采用较新的语法,恕我直言。

于 2014-07-03T11:29:17.017 回答