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

delegate , action and passing lambda expression as delegate parameter

我看过这个问题diference between delegate and action

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

来引用它
public static void Print()
{
    Console.WriteLine("Printing ..");
}

我创建了这两个将调用 Print 方法的方法,如您所见,第一个具有 Action 类型参数,第二个具有 Delegate 类型参数,这些参数将引用方法“Print”

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

}

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

public static void SomeHowMethod()
{
    DelegateParamMethod(() => Print());
    ActionParamMethod(() => Print());
}

当我尝试将 lambda 表达式传递给接受委托参数的方法时出现此错误

Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type

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

问题是您没有提供要调用的委托类型。您正在寻找类似的东西:

DelegateParamMethod((Action)(() => Print()));

您不应在您的代码中引用 Delegate,它是代表的基础 class,但不应该像您在此处所做的那样使用。

相反,您应该选择一个委托类型(如您的 Action 示例)并将其用作参数。

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

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

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

DelegateParamMethod((Action<string>)(x => Console.WriteLine(x));

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

var x = () => Print("Hello world");