我经常被问及这个问题,我想征求一些关于如何最好地描述它们之间区别的意见。
delegate Int32 BinaryIntOp(Int32 x, Int32 y);
BinaryIntOp类型的变量可以分配方法或lambda,只要签名相同:两个Int32参数和一个Int32返回值。
可以这样定义lambda:
BinaryIntOp sumOfSquares = (a, b) => a*a + b*b;
Int32 DiffOfSquares(Int32 x, Int32 y)
{
return x*x - y*y;
}
Func<Int32, Int32, Int32> funcPtr = DiffOfSquares;
一个不同之处是匿名委托可以省略参数,而Lambda表达式必须匹配精确的签名。例如:
public delegate string TestDelegate(int i);
public void Test(TestDelegate d)
{}
你可以以下四种方式调用它(请注意,第二行有一个匿名委托,没有任何参数):
Test(delegate(int i) { return String.Empty; });
Test(delegate { return String.Empty; });
Test(i => String.Empty);
Test(D);
private string D(int i)
{
return String.Empty;
}
您不能传递没有参数的 Lambda 表达式或没有参数的方法。这些是不允许的:
Test(() => String.Empty); //Not allowed, lambda must match signature
Test(D2); //Not allowed, method must match signature
private string D2()
{
return String.Empty;
}
委托类似于函数指针/方法指针/回调函数(自己选择),而lambda表达式则是简化的匿名函数。至少这就是我告诉人们的。
delegate string MyDelegate(int param1);
委托没有实现主体。
lambda是一个函数调用,其签名与委托相匹配。对于上述委托,您可以使用以下任何一个:
(int i) => i.ToString();
(int i) => "ignored i";
(int i) => "Step " + i.ToString() + " of 10";
Delegate
类型的名称不太准确,实际上创建一个 Delegate
类型的对象会创建一个可以保存函数(无论是 lambda、静态方法还是类方法)的变量。委托本质上就是一个函数指针。Lambda表达式可以转换为委托,也可以转换为LINQ表达式树。例如,
Func<int, int> f = x => x + 1;
Expression<Func<int, int>> exprTree = x => x + 1;
虽然我在这方面的经验不是很丰富,但我认为委托是对任何函数的封装,而Lambda表达式本身就是一个匿名函数。
简短版:
委托是代表方法引用的类型。C# lambda 表达式是创建 委托 或 表达式树 的语法。
稍微详细版:
委托不是如接受的答案所说的"变量的名称"。
委托是一个类型(实际上是一个类型,如果您检查 IL,则是类),它代表对方法的引用 (learn.microsoft.com)。
可以初始化此类型以将其实例与具有兼容签名和返回类型的任何方法关联。
namespace System
{
// define a type
public delegate TResult Func<in T, out TResult>(T arg);
}
// method with the compatible signature
public static bool IsPositive(int int32)
{
return int32 > 0;
}
// initiated and associate
Func<int, bool> isPositive = new Func<int, bool>(IsPositive);
Func<int, bool> isPositive = delegate(int int32)
{
return int32 > 0;
};
Func<int, bool> isPositive = (int int32) =>
{
return int32 > 0;
};
lambda表达式只是委托的语法糖。编译器最终会将lambda表达式转换为委托。
我相信它们是相同的:
Delegate delegate = x => "hi!";
Delegate delegate = delegate(object x) { return "hi";};