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

时间:2015-07-17 10:34:46

标签: c# delegates implicit-conversion

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

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

方法组DoSomeStuffAction的明确演员引起了我的注意,所以我一直在深入研究代表和其他相关主题。

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

为什么方法组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作为参数时,为什么编译器无法进行隐式转换?说实话,我不相信我自己的逻辑,但我仍然不确定我错过了什么。

1 个答案:

答案 0 :(得分:3)

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

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

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

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

它只会起作用。

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