为什么匿名方法可以作为操作隐式传递

本文关键字:操作 方法 为什么 | 更新日期: 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:

所做的评论让我找到了我正在寻找的答案。