c# - 参数类型 'void' 不可分配给参数类型 'System.Action'

标签 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("");
    }
}

前 2 个调用有效,但我想知道为什么第 3 个调用无效。我不喜欢 Do2 中的代码,因为我在其中输入类型 action("") 以使其正常工作似乎很奇怪。

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

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

最佳答案

dsufac.Do(WriteToConsoleWithSomethingExtra("Test"));

实际上首先调用函数 ( WriteToConsoleWithSomethingExtra("Test") ) 然后尝试将结果传递给 Do .由于没有结果 ( void ),因此不可能。

你真正想要的是:

dsufac.Do(() => WriteToConsoleWithSomethingExtra("Test"));

内部声明一个不带任何参数的函数(() =>位),调用WriteToConsoleWithSomethingExtra("Test")执行时。 然后你的dsufac.Do调用将收到一个操作,就像它期望的那样。

至于Do2 - 你已经宣布它正在服用Action<String> ,这意味着 action是一个接受一个参数的函数。你必须给它传递一个字符串。该字符串可能为空,就像在您的 action("") 中一样例如,它也可能从外部传入,如下所示:

dsufac.Do3(WriteToConsole, "Test");

...

internal void Do3(Action<String> action, String str)
{
    action(str);
}

关于c# - 参数类型 'void' 不可分配给参数类型 'System.Action',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3387812/

相关文章:

c# - 读取文件 A 并附加到文件 B,跳过一些字节

c# - 在 MVVM 中阻塞 UI 线程

c# - MongoDB 反序列化/对象的反序列化

c# - 什么时候显式使用 delegate 关键字而不是 lambda 是更好的做法?

c# - 使用 C# 删除分隔符

c# - 在 C# 中隐藏另一个应用程序的系统托盘

c# - PUT方法可以插入、删除。那么为什么我们必须使用 POST 方法而不是 PUT/DELETE/GET 方法

asp.net-mvc - 在C#中,如何从byte[]得知文件类型?

c# - 从 C# 调用对话窗口

c# - 工具提示闪烁。