委托,动作并将lambda表达式作为委托参数传递

时间:2015-01-08 16:14:22

标签: c# lambda delegates

我看一下这个问题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表达式传递给接受Delegate参数的方法时,我收到此错误

  

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

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

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:4)

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

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

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

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

你不应该在你的代码中引用Delegate,它是代表的基类,但不能像你在这里那样使用。

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