C# 隐式地将方法组转换为委托(对于Control.Invoke的参数)
我正在开发一个Windows窗体应用程序,它包含一些自定义控件,这些控件的方法可以从UI线程以外的线程调用。因此,这些方法看起来有点像这样以防止异常:C# 隐式地将方法组转换为委托(对于Control.Invoke的参数),c#,delegates,implicit-conversion,C#,Delegates,Implicit Conversion,我正在开发一个Windows窗体应用程序,它包含一些自定义控件,这些控件的方法可以从UI线程以外的线程调用。因此,这些方法看起来有点像这样以防止异常: public void DoSomeStuff() { if (InvokeRequired) { Invoke((Action)DoSomeStuff); } else { // Actually do some stuff. } } 方法组dosomething
public void DoSomeStuff()
{
if (InvokeRequired)
{
Invoke((Action)DoSomeStuff);
}
else
{
// Actually do some stuff.
}
}
方法组dosomething
到动作的显式转换引起了我的注意,因此我比以前更深入地研究了学员和其他相关主题
虽然我在这里看到了一些相关的问题,但我还没有找到我的确切答案,那就是:
在这种情况下,为什么方法组DoSomeStuff
需要显式强制转换到操作
?
如果删除强制转换,则会出现两个错误:
错误102参数1:无法从“方法组”转换为
'系统.代理'
错误101与的最佳重载方法匹配
'System.Windows.Forms.Control.Invoke(System.Delegate,参数
对象[])'有一些无效参数
编译器显然对要使用的Invoke
重载感到困惑,这一事实似乎是一个很大的暗示,但我仍然不确定为什么它不能确切地理解这一点。我希望编译器推断出应该使用的是Invoke
的第一个重载,它接受一个委托
参数
我希望如此,因为如果代码是这样编写的,那么就没有问题了:
Action a = DoSomeStuff;
Invoke(a);
方法组DoSomeStuff
可以隐式转换为Action
委托类型,Action
从System.delegate
派生(技术上?),因此Invoke
可以毫无困难地处理参数a
。但是,当我试图直接将dosomething
作为参数传递时,为什么编译器不能完成隐式转换呢?老实说,我不相信我自己的逻辑,但我仍然不确定我遗漏了什么。问题不是编译器在选择重载时遇到问题。“最佳匹配”重载是您想要的重载,但它具有无效参数。C语言没有定义从方法组(DoSomeStuff
)到System.Delegate
的任何隐式转换
您可能会说,编译器应该只选择一种操作
/Func
类型,这是作为语言特性请求的。现在这不是C#的一部分。(我不知道为什么,我希望语言申请通过。)
System.Windows.Forms.Control.Invoke是在.NET1.0中创建的。今天,我们将使用以下签名:
void Invoke(Action action);
Task InvokeAsync(Action action);
而且它将简单地工作
尝试将迁移到wait
,这就不再是一个问题了。>您可能会说编译器应该只选择一种操作/Func类型,这已被请求作为一种语言功能,这很容易被分解:void Foo(out string abc)代码>不能使用操作
或函数
表示。如果他们将Action/Func推断实现为一种语言功能,则该功能将被破坏。@GeirGrusom使用此特定签名,转换可能会失败(静态)。这是一种罕见的情况,我认为在这里显示错误是可以的。并非所有方法都可以表示为操作/函数,但其中99%都可以在实践中使用。在有意义的地方,所有委托类型都应该在结构上用隐式转换来处理。我认为这不好。显示错误是因为该功能基本上被破坏了。我不太明白你在这里说的。为什么编译器在某些特殊情况下不能推断方法是动作或Func,这意味着在所有情况下都应该显示错误?按照这种逻辑,DoSomeStuff隐式转换为动作(在原始问题中)也应该是错误的吗?