对于匿名方法,是否存在委托语法优于 lambda 表达式的情况?

发布于 2024-07-06 10:55:20 字数 130 浏览 8 评论 0原文

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

任何我们仍然需要使用委托和 lambda 表达式的地方都无法工作吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

醉生梦死 2024-07-13 10:55:20

是的,有些地方直接使用匿名委托和 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’,因为它不是委托类型”。

Yes there are places where directly using anonymous delegates and lambda expressions won't work.

If a method takes an untyped Delegate then the compiler doesn't know what to resolve the anonymous delegate/lambda expression to and you will get a compiler error.

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();
}

The failing line of code will get the compiler error "Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type".

治碍 2024-07-13 10:55:20

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

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

可以替换为

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

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())
又爬满兰若 2024-07-13 10:55:20

Lambda 表达式不是(也无意成为)取代(隐藏)委托的灵丹妙药。 它对于本地的小事情非常有用,例如:

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

另一方面,很容易滥用它们。 长或/和复杂的 lambda 表达式往往是:

  1. 对于新开发人员来说难以理解
  2. 面向对象较少
  3. 更难阅读

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

Lambda expression is not (and was not meant to be) a silver bullet that would replace (hide) delegates. It is great with small local things like:

List<string> names = GetNames();
names.ForEach(Console.WriteLine);
  1. it makes code more readable thus simple to understand.
  2. It makes code shorter thus less work for us ;)

On the other hand it is very simple to misuse them. Long or/and complex lambda expressions are tending to be:

  1. Hard to understand for new developers
  2. Less object oriented
  3. Much harder to read

So “does it mean we don’t have to use delegates or anonymous methods anymore?” No – use Lambda expression where you win time/readability otherwise consider using delegates.

凡尘雨 2024-07-13 10:55:20

较旧的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"); };

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

One not so big advantage for the older delegate syntax is that you need not specify the parameters if you dont use it in the method body. From msdn

There is one case in which an anonymous method provides functionality
not found in lambda expressions. Anonymous methods enable you to omit
the parameter list. This means that an anonymous method can be
converted to delegates with a variety of signatures. This is not
possible with lambda expressions.

For example you can do:

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

While this fails:

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

This technique mostly comes handy when writing event-handlers, like:

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

This is not a strong advantage. It's better to adopt the newer syntax always imho.

淡写薰衣草的香 2024-07-13 10:55:20

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

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

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

Delegate have two meanings in C#.

The keyword delegate can be used to define a function signature type. This is usually used when defininge the signature of higher-order functions, i.e. functions that take other functions as arguments. This use of delegate is still relevant.

The delegate keyword can also be used to define an inline anonymous function. In the case where the function is just a single expression, the lambda syntax is a simpler alternative.

夏末的微笑 2024-07-13 10:55:20

Lambda 表达式只是“语法糖”,编译器将为您生成适当的委托。 您可以使用 Lutz Roeder 的 Reflector 来调查这一点。

Lambda expressions are just "syntactic sugar", the compiler will generate appropriate delegates for you. You can investigate this by using Lutz Roeder's Reflector.

伴我心暖 2024-07-13 10:55:20

Lamda 只是委托的语法糖,它们不仅仅是内联的,您可以执行以下操作:

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

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

Lamda's are just syntactic sugar for delegates, they are not just inline, you can do the following:

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

And delegates are still used when defining events, or when you have lots of arguments and want to actually strongly type the method being called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文