问题描述
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);
产生编译器错误
produces the compiler error
错误105的最佳重载方法匹配 System.Windows.Forms.Control.BeginInvoke(System.Delegate)有一定的 无效的参数
一样
BeginInvoke(ShowProcessErrors, new object[] { process });
这两种方法调用只编译如果我改变他们explitly创建一个委托并传递。下面的两个编译罚款:
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;
编译器可以识别您要的方法组转换为委托并插入转换为您服务。它产生白细胞介素,有效地说道:
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#,一般情况下不会插入你没有使用到EX pressions类型。因为它不知道你想要的方法组转换为何种委托,编译器会产生错误。
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委托的类型推断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!