隐式地将方法组转换为委托(用于Control.Invoke的参数)
本文关键字:Control 用于 Invoke 参数 方法 转换 | 更新日期: 2023-09-27 18:03:07
我正在开发一个Windows窗体应用程序,它包含带有方法的自定义控件,这些方法可以从UI线程以外的线程调用。因此,这些方法看起来有点像这样,以防止异常:
public void DoSomeStuff()
{
if (InvokeRequired)
{
Invoke((Action)DoSomeStuff);
}
else
{
// Actually do some stuff.
}
}
方法组DoSomeStuff
到Action
的显式强制转换引起了我的注意,因此我一直在比以前更深入地研究委托和其他相关主题。
虽然我在这里看到了一些相关的问题,但我还没能找到我的确切答案,那就是:
在这种情况下,为什么方法组DoSomeStuff
需要显式转换为Action
?
如果我删除强制转换,那么我得到两个错误:
错误102参数1:无法从"方法组"转换为的系统。委托'
错误101最佳重载方法匹配"System.Windows.Forms.Control.Invoke(系统。委托,参数对象[])'有一些无效参数
编译器显然对使用Invoke
的哪个重载感到困惑,这似乎是一个相当大的暗示,但我仍然不确定为什么它不能弄清楚。我希望编译器能推断出Invoke
的第一个重载(它接受一个Delegate
参数)是应该使用的重载。
我希望这样做,因为如果代码像这样写的话没有问题:
Action a = DoSomeStuff;
Invoke(a);
方法组DoSomeStuff
可以隐式地转换为Action
委托类型,Action
(技术上?)派生自System.Delegate
,因此Invoke
可以毫无困难地处理参数a
。但是,为什么不能隐式转换是由编译器当我试图传递DoSomeStuff
作为参数直接?老实说,我不相信我自己的逻辑,但我仍然不确定我错过了什么。
问题不在于编译器在选择重载时遇到麻烦。"最佳匹配"重载是您想要的重载,但它具有无效参数。c#语言没有定义任何从方法组(DoSomeStuff
)到System.Delegate
的隐式转换。
你可能会说编译器应该只选择Action
/Func
类型之一,这已经被要求作为一种语言特性。现在这还不是c#的一部分。(我不知道为什么;我希望语言请求能通过。
System.Windows.Forms.Control.Invoke
在。net 1.0中创建。今天,人们会使用以下签名:
void Invoke(Action action);
Task InvokeAsync(Action action);
它会简单地工作。
尝试迁移到await
,这不再是一个问题。
使用c# 10和Visual Studio 2022,您不再需要显式强制转换(自然函数类型)。