将方法组隐式转换为Delegate(对于Control.Invoke的参数)
我正在使用Windows窗体应用程序,它包含自定义控件,这些控件可能会从UI线程以外的线程调用。 因此,这些方法看起来有点像这样以防止exception:
public void DoSomeStuff() { if (InvokeRequired) { Invoke((Action)DoSomeStuff); } else { // Actually do some stuff. } }
方法组DoSomeStuff
对Action
的显式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
委托类型, Action
从System.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
,这不再是一个问题。