为什么匿名方法可以作为操作隐式传递
本文关键字:操作 方法 为什么 | 更新日期: 2023-09-27 17:55:22
可能的重复项:
为什么在作为纯委托参数提供时必须强制转换 lambda 表达式
Control.Invoke
接受Delegate
参数类型。 如果不告诉编译器我要传递哪种类型的委托,我就无法将 lamba 表达式作为Delegate
传递。
textBox1.Invoke(() => { MessageBox.Show("Hello World"); }); //illegal
在这种情况下,我可以投Action
textBox1.Invoke((Action)(() => { MessageBox.Show("Hello World"); })); //legal
但是,我可以通过扩展方法创建一个速记方法(我已经看到Marc Gravell这样做了):
public static void Invoke(this Control control, Action action)
{
control.Invoke((Delegate)action);
}
现在我的速记工作...
textBox1.Invoke(() => { MessageBox.Show("Hello World"); }); //legal
为什么编译器可以确定匿名方法是扩展方法中的操作,但编译器无法确定lamba是操作,因此在Control.Invoke
的情况下是法律Delegate
?
首先,编译器足够聪明,可以确定参数的类型是 Action
(而不是说 Action<T>
)。 更重要的是,编译器可以假设我的意思是Action
而不是Expression
,因为消除了歧义。 如果我做一些愚蠢的事情来重现歧义......假设通过新的扩展方法创建重载:
public static void Invoke(this Control control, Expression<Action> action)
{
Console.WriteLine("hi");
//control.Invoke((Delegate)action);
}
编译器也会捕获它:
The call is ambiguous between the following methods or properties:
所做的评论让我找到了我正在寻找的答案。