将方法组隐式转换为委托(用于 Control.Invoke 的参数) [英] Implicitly convert method group to Delegate (for argument of Control.Invoke)

查看:26
本文介绍了将方法组隐式转换为委托(用于 Control.Invoke 的参数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 Windows 窗体应用程序,它包含自定义控件以及可以从 UI 线程以外的线程调用的方法.所以这些方法因此看起来有点像这样来防止异常:

I'm working on a Windows Forms application, and it contains custom controls with methods that can potentially be called from threads other than the UI thread. So these methods therefore look a bit like this to prevent exceptions:

public void DoSomeStuff()
{
    if (InvokeRequired)
    {
        Invoke((Action)DoSomeStuff);
    }
    else
    {
        // Actually do some stuff.
    }
}

方法组 DoSomeStuffAction 的显式转换引起了我的注意,因此我对委托和其他相关主题的研究比我以前更深入之前.

The explicit cast of the method group DoSomeStuff to an Action caught my attention, and so I've been looking into delegates and other related subjects more deeply than I have before.

虽然我在这里看到了一些相关的问题,但我一直无法找到我的确切答案,即:

Although I've seen some related questions here, I haven't been able to find exactly the answer to mine, which is:

在这种情况下,为什么方法组 DoSomeStuff 需要显式转换为 Action?

Why does the method group DoSomeStuff require explicit casting to an Action in this case?

如果我删除演员表,则会收到两个错误:

If I remove the cast, then I get two errors:

错误 102 参数 1:无法从方法组"转换为'System.Delegate'

Error 102 Argument 1: cannot convert from 'method group' to 'System.Delegate'

错误 101 的最佳重载方法匹配'System.Windows.Forms.Control.Invoke(System.Delegate,参数object[])' 有一些无效参数

Error 101 The best overloaded method match for 'System.Windows.Forms.Control.Invoke(System.Delegate, params object[])' has some invalid arguments

编译器显然对使用哪个 Invoke 重载感到困惑这一事实似乎是一个很大的提示,但我仍然不确定为什么它无法弄清楚这一点.我希望编译器能够推断出应该使用单个 Delegate 参数的 Invoke 的第一个重载.

The fact that the compiler is apparently confused about which overload of Invoke to use seems like a pretty big hint, but I'm still not sure about why exactly it can't figure that out. I would expect the compiler to deduce that the first overload of Invoke, which takes a single Delegate argument, is the one that should be used.

我希望因为这样写代码没有问题:

I would expect that because there is no problem if the code is written like this:

Action a = DoSomeStuff;
Invoke(a);

方法组 DoSomeStuff 可以隐式转换为 Action 委托类型,并且 Action 派生自(技术上?)System.Delegate,所以 Invoke 可以毫无问题地处理参数 a.但是,当我尝试直接将 DoSomeStuff 作为参数传递时,为什么编译器不能完成隐式转换呢?老实说,我不相信我自己的逻辑,但我仍然不确定我错过了什么.

The method group DoSomeStuff can be implicitly converted to the Action delegate type, and Action derives (technically?) from System.Delegate, so Invoke can handle the argument a without any trouble. But then why can't the implicit conversion be done by the compiler when I try to pass DoSomeStuff as the argument directly? To be honest I'm not convinced by my own logic here, but I still am not sure what I'm missing.

推荐答案

问题不在于编译器无法选择重载.最佳匹配"重载是您想要的重载,但它具有无效参数.C# 语言没有定义任何从方法组 (DoSomeStuff) 到 System.Delegate 的隐式转换.

The problem is not that the compiler has trouble picking an overload. The "best match" overload is the one you want but it has invalid arguments. The C# language does not define any implicit conversion from method group (DoSomeStuff) to System.Delegate.

您可能会说编译器应该只选择一种 Action/Func 类型,而这已作为语言特性被请求.现在这不是 C# 的一部分.(我不知道为什么;我希望语言请求能够通过.)

You might say that the compiler should just pick one of the Action/Func types and this has been requested as a language feature. Right now this is not part of C#. (I don't know why; I hope the language request goes through.)

System.Windows.Forms.Control.Invoke 是在 .NET 1.0 中创建的.今天,人们会使用以下签名:

System.Windows.Forms.Control.Invoke was created in .NET 1.0. Today, one would use the following signatures:

void Invoke(Action action);
Task InvokeAsync(Action action);

而且它会简单地工作.

尝试迁移到 await,这不再是一个问题.

Try to make the migration to await and this stops being a concern.

这篇关于将方法组隐式转换为委托(用于 Control.Invoke 的参数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆