在.NET Framework中,lambdas和委托之间有什么区别?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

我被问了很多这个问题,我想我会征求一些关于如何最好地描述差异的意见。

提问于
用户回答回答于

他们实际上是两个完全不同的东西。“委托”实际上是一个变量的名称,它包含对方法或lambda的引用,而lambda是没有永久名称的方法。

兰姆达斯非常像其他方法,除了一些细微的差异。

  1. 常规方法在“语句”中定义并绑定到永久名称,而lambda则在“表达式”中“随时”定义,并且没有永久名称。
  2. 一些lambda可以用于.NET表达式树,而方法不能。

代表是这样定义的:

delegate Int32 BinaryIntOp(Int32 x, Int32 y);

BinaryIntOp类型的变量可以有一个方法或labmda分配给它,只要签名是相同的:两个Int32参数和一个Int32返回值。

lambda可以像这样定义:

BinaryIntOp sumOfSquares = (a, b) => a*a + b*b;

另外需要注意的是,虽然通用的Func和Action类型通常被认为是“lambda类型”,但它们就像任何其他代表一样。关于他们的好处是,他们基本上为可能需要的任何类型的代理定义名称(最多4个参数,尽管您可以添加更多自己的参数)。因此,如果使用各种各样的委托类型,但只能使用一次,则可以使用Func和Action避免使用委托声明混淆您的代码。

以下是Func和Action如何“不仅仅是lambdas”的说明:

Int32 DiffOfSquares(Int32 x, Int32 y)
{
  return x*x - y*y;
}

Func<Int32, Int32, Int32> funcPtr = DiffOfSquares;

另一个有用的知识是,具有相同签名但名称不同的委托类型(不是方法本身)不会隐式地相互转换。这包括Func和Action代表。但是,如果签名是相同的,则可以明确地在它们之间进行投射。

多走一步......在C#中,函数是灵活的,使用lambdas和委托。但是C#没有“一流的功能”。您可以使用分配给委托变量的函数名来实质上创建表示该函数的对象。但它确实是一个编译器技巧。如果你通过写一个点后面的函数名称来开始一个语句(即尝试对函数本身进行成员访问),你会发现没有成员可以参考。甚至不是来自Object的。这可以防止程序员做一些有用的事情(当然也有潜在的危险),例如添加可以在任何函数上调用的扩展方法。你可以做的最好的事情是扩展Delegate类本身,这当然也是有用的,但不是那么多。

James Hart提出了一个非常重要的技术,但lambdas和代表不是.NET实体(即CLR没有委托或lambda的概念),而是框架和语言结构。

用户回答回答于

这个问题有点含糊不清,这就解释了你所得到的答案存在很大差异。

你实际上问了.NET框架中lambdas和委托的区别是什么,这可能是许多事情之一。你问:

  • 在C#(或VB.NET)语言中,lambda表达式与匿名代表之间有什么区别?
  • System.Linq.Expressions.LambdaExpression对象和.NET 3.5中的System.Delegate对象有什么区别?
  • 或者是在这些极端之间或附近的某个地方?

有些人似乎试图给你“C#Lambda表达式和.NET System.Delegate之间有什么区别?”这个问题的答案,这个问题没有什么意义。

.NET框架本身并不了解匿名代理,lambda表达式或闭包的概念 - 这些都是由语言规范定义的东西。想想C#编译器如何将匿名方法的定义转换为生成类中的方法,并使用成员变量保持闭包状态; 到.NET,没有什么匿名的委托; 它只是写给它的C#程序员的匿名。这同样适用于分配给委托类型的lambda表达式。

什么.NET DOES理解为代表的想法-它描述的方法签名类型,它们的实例代表或者绑定调用特定对象上,或者绑定调用特定方法,以特定的方法对特定类型,可以对被调用该类型的任何对象,其中所述方法符合所述签名。这些类型都从System.Delegate继承。

.NET 3.5还引入了System.Linq.Expressions命名空间,该命名空间包含用于描述代码表达式的类 - 它也可以表示对特定类型或对象上方法的绑定或未绑定调用。然后可以将LambdaExpression实例编译为实际的委托(由此基于表达式的结构的动态方法被编码,并返回指向它的委托指针)。

在C#中,您可以通过将lambda表达式分配给所述类型的变量来生成System.Expressions.Expression类型的实例,这将生成适当的代码以在运行时构造表达式。

当然,如果你问有什么区别lambda表达式和C#匿名方法之间,毕竟,那么这一切是非常irelevant,在这种情况下,主要的区别是简洁,当你不其上倾向于匿名委托不关心参数,不要计划返回一个值,并且当你想要输入推断参数和返回类型时,不要计划返回一个值。

而lambda表达式支持表达式生成。

扫码关注云+社区