【问题标题】:Why can't an Action<Object> delegate be used as a WaitCallback for Threadpool?为什么不能将 Action<Object> 委托用作线程池的 WaitCallback?
【发布时间】:2017-04-27 04:20:50
【问题描述】:

代表WaitCallbackAction&lt;Object&gt; 共享相同的签名。尽管如此,正如下面的代码所证明的,它们不能被视为同一类型。

static void Main(string[] args)
{
    WaitCallback wcb = (o) => Console.WriteLine("Hello from wcb delegate");
    ThreadPool.QueueUserWorkItem(wcb);//works

    Action<object> action = (o) => Console.WriteLine("Hello from action<object> delegate");
    ThreadPool.QueueUserWorkItem(action);//does not compile: Cannot convert from Action<object> to WaitCallback  

    Console.ReadLine();
}

我对这个观察有两个问题:

  1. 为什么签名相同但名称不同的委托不被视为同一类型?语言设计团队是否会做出不同的选择,或者会导致不一致或其他问题?

  2. Action 代表在 .NET 框架 2.0 中引入时,WaitCallback 已经存在。我想知道如果不是这种情况,是否有理由引入额外的委托类型WaitCallback 而不是使用Action

【问题讨论】:

    标签: c# .net delegates threadpool


    【解决方案1】:

    从类型系统的角度来看,WaitCallbackAction&lt;object&gt; 是不同的类型,它们之间不存在隐式转换。因此,您不能在需要 WaitCallback 的地方使用 Action&lt;object&gt;。然而,实际的方法被引用并用作委托,只关心它们的参数列表和返回类型的兼容性,所以你可以有一个匿名方法,而不是一个匿名方法

    private void Foo(object o) {
      Console.WriteLine("Hello from actual method");
    }
    

    以下几行将毫无问题地工作:

    WaitCallback wcb = Foo;
    Action<object> action = Foo;
    ThreadPool.QueueUserWorkItem(Foo);
    

    请注意,在这种情况下,方法的 name 用于引用它,它的解析和处理方式与将某种类型的变量传递给方法完全不同。对于后者,您完全受制于实际类型,它们的转换和委托一点也不特别。

    该规范还包含以下注释:

    C# 中的委托类型是名称等价的,而不是结构上等价的。具体来说,具有相同参数列表和返回类型的两种不同委托类型被视为不同的委托类型。

    (警告:推测;我不在语言设计团队中) 所以这是一个有意识的选择,考虑到我上面写的内容,允许您要求的内容可能并非不可能,但这将是重载解析如何工作的一个主要例外。所以我猜这个电话是为了简化语言。此外,在 C# 1 时代,实际上在结构上兼容的委托可能并不多。

    至于您的第二点,在这种情况下,他们可能会选择Action。作为示例,请参见 Task.Run 方法,该方法采用 Action 而不是自定义委托。对于不带参数或只带一个参数的操作,这似乎是一个相当明显的情况,不引入新的委托类型。但是,对于 Action&lt;string, string, int, double&gt; 或等效的 Func 类型,我想拥有一个可以记录的实际命名类型将比使用通用 ActionFunc 类型好得多。

    【讨论】:

    • 感谢乔伊的详尽回答。你的措辞方式让我对代表的工作方式有了更多的了解。您对称为委托的方法名称的解释是一个很好的奖励。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 2010-12-22
    • 2014-04-25
    相关资源
    最近更新 更多