有没有办法引起传递给Control.BeginInvoke的委托的类型推断? [英] Is there a way to cause type inference of the delegate passed to Control.BeginInvoke?

查看:138
本文介绍了有没有办法引起传递给Control.BeginInvoke的委托的类型推断?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Control.BeginInvoke

在这两种情况下,似乎很清楚编译器具有推断委托类型所需的所有信息。然而,在这两种情况下,类型推断似乎都有效:

In both cases, it seems clear that the compiler has all the information it needs to infer the delegate type. Yet in neither case does the type inference seem to work:

 BeginInvoke(myMethodThatTakesNoParams);

产生编译器错误


错误105最好的重载方法匹配
'System.Windows.Forms.Control.BeginInvoke(System.Delegate)'有一些
无效参数

Error 105 The best overloaded method match for 'System.Windows.Forms.Control.BeginInvoke(System.Delegate)' has some invalid arguments

BeginInvoke(ShowProcessErrors, new object[] { process });

只要我更改它们,方法调用才能编译,以便明确地创建一个委托并传递。以下两个编译都很好:

Both method calls only compile if I change them to explitly create a delegate and pass that. Both of the following compile fine:

BeginInvoke(new MethodInvoker(myMethodThatTakesNoParams));

BeginInvoke(new ProcessErrorDelegate(ShowProcessErrors), new object[] { process });

似乎没有任何明显的原因,为什么类型推论不会在这里工作。有没有办法调用 BeginInvoke 而不显式创建委托?

There doesn't seem to be any obvious reason why type inference won't work here. Is there a way to call BeginInvoke without explicitly creating a delegate?

推荐答案

问题是 myMethodThatTakesNoParams 不是一个真正的委托,而是编译器所谓的方法组。方法组不是CLR中的实际类型。它必须转换为要使用的委托类型。当您使用这样的方法组时:

The issue is that myMethodThatTakesNoParams isn't really a delegate but a so-called "method group" by the compiler. A method group isn't a real type in the CLR. It must be converted to delegate type to be used. When you use a method group like this:

Action a = myMethodThatTakesNoParams;

编译器认识到要将方法组转换为代理,并为您插入转换。它产生的IL有效地说:

The compiler recognizes that you want to convert the method group to a delegate and inserts the conversion for you. It produces IL that effectively says:

Action a = new Action(myMethodThatTakesNoParams);

当你说:

Delegate d = myMethodThatTakesNoParams

编译器不知道该怎么做。理论上可以为您选择任何兼容的委托类型,但C#通常不会将您未使用的类型插入到表达式中。因为它不知道你想要转换方法组的委托,编译器会产生一个错误。

The compiler doesn't really know what to do. It could theoretically pick any compatible delegate type for you, but C#, in general, does not insert types you did not use into expressions. Since it does not know what delegate you want the method group converted to, the compiler produces an error.

我在我的例子中使用变量赋值,但是同样的逻辑适用于参数到方法。

I used variable assignment in my examples, but the same logic applies for parameters to methods.

一个工作是编写自己的扩展方法,其中有一个特定的委托类型:

A work around would be to write your own extension method that has a specific delegate type in it:

static class ControlExtensions
{
    public static IAsyncResult BeginInvoke(this Control c, Action a)
    {
        return c.BeginInvoke(a);
    }
}

这篇关于有没有办法引起传递给Control.BeginInvoke的委托的类型推断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆