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

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

问题描述

我正在使用Windows Forms应用程序,它包含一些自定义控件,这些控件的方法可以从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.
    }
}

方法组<$ c $的显式转换c> DoSomeStuff 到 Action 引起了我的注意,因此我比以往更加深入地研究了代表和其他相关主题。

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,params
object [])'有一些无效的参数

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

编译器显然混淆了一个事实关于使用 Invoke 的重载似乎是一个很大的提示,但是我仍然不确定为什么它无法弄清楚。我希望编译器推断出 Invoke 的第一个重载就是一个,它只需要一个 Delegate 参数。

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.

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

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