参数类型'System.Action'不能赋予参数类型'void'

Nyl*_*ska 16 c# c#-3.0

这是我的测试代码:

class PassingInActionStatement
{
    static void Main(string[] args)
    {
        var dsufac = new DoSomethingUsefulForAChange();

        dsufac.Do(WriteToConsole);
        dsufac.Do2(s => WriteToConsoleWithSomethingExtra("Test"));
        dsufac.Do(WriteToConsoleWithSomethingExtra("Test")); // Does not compile
    }

    internal static void WriteToConsole()
    {
        Console.WriteLine("Done");
    }

    internal static void WriteToConsoleWithSomethingExtra(String input)
    {
        Console.WriteLine(input);
    }
}

internal class DoSomethingUsefulForAChange
{
    internal void Do(Action action)
    {
        action();
    }

    internal void Do2(Action<String> action)
    {
        action("");
    }
}
Run Code Online (Sandbox Code Playgroud)

前2个电话有效,但我想知道为什么第3个电话没有.我不喜欢Do2中的代码,因为我action("")在那里有类型类型以使其工作似乎很奇怪.

有人可以解释一下我不明白的两件事吗?

  1. 为什么我不能通过调用Do来编写第三行
  2. 为什么我必须写动作("")才能让它在Do2中工作

Rom*_*kov 34

dsufac.Do(WriteToConsoleWithSomethingExtra("Test"));
Run Code Online (Sandbox Code Playgroud)

实际上调用函数first(WriteToConsoleWithSomethingExtra("Test"))然后尝试将结果传递给Do.由于没有result(void),所以不可能.

你真正想要的是这个:

dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test"));
Run Code Online (Sandbox Code Playgroud)

内部部分声明一个不执行任何操作的函数(() =>位),WriteToConsoleWithSomethingExtra("Test")执行时调用该函数.然后你的dsufac.Do电话将收到一个他们预期的行动.

至于Do2- 你已经宣布它为take Action<String>,这意味着这action是一个带有一个参数的函数.你必须传递一个字符串.该字符串可能是空的,就像在您的action("")示例中一样,或者它可能在外部传递,如下所示:

dsufac.Do3(WriteToConsole, "Test");

...

internal void Do3(Action<String> action, String str)
{
    action(str);
}
Run Code Online (Sandbox Code Playgroud)