gpt4 book ai didi

c# - 为什么不能将 Action 委托(delegate)用作线程池的 WaitCallback?
转载 作者:行者123 更新时间:2023-12-04 03:15:49 28 4
gpt4 key购买 nike

与会委托(delegate)WaitCallbackAction<Object>共享相同的签名。尽管如此,正如下面的代码所证明的那样,它们不能被视为同一类型。

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();
}
我对这个观察有两个问题:
  • 为什么签名相同但名称不同的委托(delegate)不被视为同一类型?语言设计团队是否会做出不同的选择,或者会导致不一致或其他问题?
  • Action .NET 框架 2.0 中引入的委托(delegate),WaitCallback已经存在。我想知道如果不是这样,是否有理由引入额外的委托(delegate)类型 WaitCallback而不是使用Action ?
  • 最佳答案

    从类型系统的角度来看 WaitCallback是与 Action<object> 不同的类型并且它们之间不存在隐式转换。所以你不能使用 Action<object>在哪里 WaitCallback是期待。但是,实际引用并用作委托(delegate)的方法只关心其参数列表和返回类型的兼容性,因此您可以使用匿名方法而不是匿名方法

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

    以下几行将毫无问题地工作:
    WaitCallback wcb = Foo;
    Action<object> action = Foo;
    ThreadPool.QueueUserWorkItem(Foo);

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

    该规范还包含以下注释:

    Delegate types in C# are name equivalent, not structurally equivalent. Specifically, two different delegate types that have the same parameter lists and return type are considered different delegate types.



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

    至于你的第二点,他们可能会选择 Action。在这种情况下。例如,参见 Task.Run 方法,它采用 Action而不是自定义委托(delegate)。对于不带参数或只带一个参数的操作,不引入新的委托(delegate)类型似乎是相当明显的情况。然而,对于像 Action<string, string, int, double> 这样的事情或等效 Func我猜想拥有一个可以记录的实际命名类型将比使用泛型 Action 好得多或 Func类型。

    关于c# - 为什么不能将 Action<Object> 委托(delegate)用作线程池的 WaitCallback?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41098518/

    28 4 0