将方法组隐式转换为Delegate(对于Control.Invoke的参数)

我正在使用Windows窗体应用程序,它包含自定义控件,这些控件可能会从UI线程以外的线程调用。 因此,这些方法看起来有点像这样以防止exception:

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

方法组DoSomeStuffAction的显式DoSomeStuff引起了我的注意,因此我一直在深入研究代表和其他相关主题。

虽然我在这里看到了一些相关的问题,但我还是找不到我的答案,这是:

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

如果我删除了演员,那么我会得到两个错误:

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

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

事实上编译器显然混淆了使用Invoke哪个重载似乎是一个相当大的提示,但我仍然不确定为什么它无法解决这个问题。 我希望编译器推断出Invoke的第一个重载是一个应该使用的,它接受一个Delegate参数。

我希望如果代码是这样编写的话没有问题:

 Action a = DoSomeStuff; Invoke(a); 

方法组DoSomeStuff可以隐式转换为Action委托类型, ActionSystem.Delegate派生(技术上?),因此Invoke可以毫无困难地处理参数a 。 但是当我尝试直接将DoSomeStuff作为参数传递时,为什么编译器无法进行隐式转换呢? 说实话,我不相信我自己的逻辑,但我仍然不确定我错过了什么。

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

您可能会说编译器应该只选择一个Action / Func类型,并且已经将其作为语言function请求。 现在这不是C#的一部分。 (我不知道为什么;我希望语言请求能够通过。)

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

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

它只会起作用。

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