它们实际上是两种截然不同的东西."Delegate"实际上是一个变量的名称,该变量包含对方法或lambda的引用,lambda是一个没有永久名称的方法.
lambda与其他方法非常相似,只是有一些细微的区别.
委托的定义如下:
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语言中,函数是灵活的,可以使用lambda和委托.但C#没有"一流的功能".可以使用分配给委托变量的函数名来创建表示该函数的对象.但这真的是一个编译技巧.如果你在开始一条语句时先写函数名,然后写一个点(即try 对函数本身进行成员访问),你会发现没有成员可供引用.甚至不是来自Object的.这会阻止程序员做一些有用(当然也有潜在危险)的事情,比如添加可以在任何函数上调用的扩展方法.您所能做的最好的事情就是扩展委托类本身,这当然也很有用,但没有那么多.
更新:另请参见Karg's answer,说明匿名代表与方法之间的区别;兰巴斯.
更新2:James Hart是一个重要的,尽管非常技术性的问题,但请注意,lambdas和代表们并非如此.NET实体(即CLR没有委托或lambda的概念),但它们是框架和语言构造.