委托、动作和传递 lambda 表达式作为委托参数

Mah*_*oud 3 c# lambda delegates

我已经查看了委托和行动之间的这个问题差异

我仍然想知道为什么我可以将 lambda 表达式传递给接受 Action 类型参数的方法,
而我不能将 lambda 表达式传递给接受 Delegate 类型参数的
方法我有这个 Print 方法,我将使用 action 和代表

public static void Print()
{
    Console.WriteLine("Printing ..");
}
Run Code Online (Sandbox Code Playgroud)

我创建了这两个方法,它们将调用 Print 方法,因为您可以看到第一个具有操作类型参数,第二个具有委托类型参数这些参数将引用方法“打印”

public static void ActionParamMethod(Action DAction)
{
    DAction();
}
public static void DelegateParamMethod(Delegate SomeDelegate)
{

}
Run Code Online (Sandbox Code Playgroud)

我将把 lambda 表达式传递给这些方法

public static void SomeHowMethod()
{
    DelegateParamMethod(() => Print());
    ActionParamMethod(() => Print());
}
Run Code Online (Sandbox Code Playgroud)

当我尝试将 lambda 表达式传递给接受 Delegate 参数的方法时,我收到此错误

无法将 lambda 表达式转换为类型“System.Delegate”,因为它不是委托类型

为什么它不是委托类型而 Action 是委托类型?
为什么我可以将 lambda 表达式传递给接受 Action 参数的方法,但我不能将 lambda 表达式传递给接受 Delegate 参数的方法?

Ser*_*rvy 7

Lambda 需要根据上下文推断使用的委托的实际类型。当尝试在Delegate预期a 的上下文中使用 lambda 时,lambda 的推理算法无法确定它应该是哪种特定类型的委托。这就像试图构造一个接口的实例;你不会知道选择哪个实现。


Sel*_*enç 6

原因是lambda 表达式没有类型 in,C#除非您将它们强制转换为具体类型。

Delegatetype 是所有委托的基类。它是一个abstract类。除非您指定一个实际的委托类型,如ActionFunc,否则您不能将 lambda 表达式作为 传递Delegate。这就像你不能实例化一个抽象类,但你可以传递一个实现它的类作为参数。如果您将 lambda 转换为任何委托类型,它将按预期工作:

DelegateParamMethod((Action<string>)(x => Console.WriteLine(x));
Run Code Online (Sandbox Code Playgroud)

您的第一种方法在不指定类型的情况下工作的原因是因为表达式可以转换为Action,否则由于与此表达式无效的相同原因,它将无效:

var x = () => Print("Hello world");
Run Code Online (Sandbox Code Playgroud)