对于匿名方法,是否存在委托语法比lambda表达式更受青睐的情况?

时间:2020-03-06 14:28:11  来源:igfitidea点击:

随着lambda表达式(内联代码)等新功能的出现,这是否意味着我们不再需要使用委托或者匿名方法?在我见过的几乎所有样本中,它都是使用新语法重写的。

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

解决方案

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

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

可以替换为

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

Lambda表达式只是"语法糖",编译器将为我们生成适当的委托。我们可以使用Lutz Roeder的Reflector对此进行调查。

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

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

并且在定义事件时,或者当我们有很多参数并且想要实际强地键入要调用的方法时,仍然使用委托。

是的,在某些地方直接使用匿名委托和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',因为它不是委托类型,因此会出错"。

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

关键字delegate可用于定义功能签名类型。通常在定义高阶函数(即以其他函数作为参数的函数)的签名时使用。委托的这种用法仍然有意义。

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

Lambda表达式不是(也不应该是)替代(隐藏)委托的灵丹妙药。很棒的地方小东西,例如:

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

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

  • 新开发者很难理解
  • 面向对象较少
  • 难以阅读

难道这意味着我们不必再使用委托或者匿名方法了吗?在赢得时间/可读性的地方不要使用Lambda表达式,否则请考虑使用委托。