2

可能重复:
为什么必须将 lambda 表达式作为普通 Delegate 参数提供

Control.Invoke接受Delegate参数类型。Delegate如果不告诉编译器我传递的是哪种类型的委托,我就无法将 Lamba 表达式作为 a传递。

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

编译器如何确定匿名方法是扩展方法中的 Action,但编译器无法确定 Lamba 是 Action,因此Delegate在 的情况下是合法的Control.Invoke

4

1 回答 1

0

首先,编译器足够聪明,可以确定参数的类型Action(而不是 say Action<T>)。更重要的是,编译器可以假设我的意思是 anAction而不是 an,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:

发表的评论让我找到了我正在寻找的答案。

于 2013-01-23T19:25:35.770 回答