Control.BeginInvoke
:
在这两种情况下,编译器显然拥有推断委托类型所需的所有信息。然而,在这两种情况下,类型推断似乎都不起作用:
BeginInvoke(myMethodThatTakesNoParams);
产生编译器错误
错误 105 最佳重载方法匹配
'System.Windows.Forms.Control.BeginInvoke(System.Delegate)' 有一些
无效参数
as does
BeginInvoke(ShowProcessErrors, new object[] { process });
如果我将这两个方法调用更改为显式创建委托并传递该委托,则它们只会编译。以下两个都可以正常编译:
BeginInvoke(new MethodInvoker(myMethodThatTakesNoParams));
and
BeginInvoke(new ProcessErrorDelegate(ShowProcessErrors), new object[] { process });
似乎没有任何明显的原因说明类型推断在这里不起作用。有办法打电话吗BeginInvoke
没有显式创建委托?
问题是myMethodThatTakesNoParams
并不是真正的委托,而是编译器所谓的“方法组”。方法组不是 CLR 中的真实类型。必须将其转换为委托类型才能使用。当您使用这样的方法组时:
Action a = myMethodThatTakesNoParams;
编译器识别出您想要将方法组转换为委托,并为您插入转换。它生成的 IL 有效地表示:
Action a = new Action(myMethodThatTakesNoParams);
当你说:
Delegate d = myMethodThatTakesNoParams
编译器并不真正知道要做什么。理论上它可以为您选择任何兼容的委托类型,但 C# 通常不会将您未使用的类型插入到表达式中。由于它不知道您希望将方法组转换为哪个委托,因此编译器会产生错误。
我在示例中使用了变量赋值,但相同的逻辑适用于方法的参数。
解决方法是编写您自己的扩展方法,其中包含特定的委托类型:
static class ControlExtensions
{
public static IAsyncResult BeginInvoke(this Control c, Action a)
{
return c.BeginInvoke(a);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)