【问题标题】:Is a lambda expression a delegate?lambda 表达式是委托吗?
【发布时间】:2012-10-18 14:07:18
【问题描述】:

我不能直接传递一个 lambda

form.Invoke(() => AMethod(form));

因为奇怪的是 lambda 不是委托类型(根据编译器错误)。我似乎记得 Jon Skeet 的 .NET 4.0 书中的不同信息。在MSDN 上它说:

lambda 表达式是一个匿名函数,您可以使用它 创建委托或表达式树类型

    public static void Main()
    {
        Form form = new Form();                                
        form.Show();
        form.Invoke(() => AMethod(form));
        Application.Run();

        Console.Read();
    }

    public static void AMethod(Form form)
    {
        form.SendToBack();
    }
}

然而,这里我们收到一个编译器错误:

无法将 lambda 表达式转换为类型“System.Delegate”,因为它 不是委托类型。

Lambda 应该是匿名代表的语法糖。那么这里的故事是什么?我错过了什么?

【问题讨论】:

  • 顺便说一句,除了下面的答案之外,请随意创建一个扩展方法,该方法采用 Action 委托类型,该委托类型反过来包装 Form.Invoke 方法。这样你就可以拥有上面的语法,而不必每次都显式地转换/构造一个Action
  • 我相信我也错过了一个微妙之处。委托关键字和委托类型之间存在区别。
  • delegate 关键字定义了一个新的MulticastDelegate 子类类型。例如:Action : MulticastDelegate : Delegate : ObjectDelegate 大写作为System.Delegate 类型存在。只是为了让事情变得有趣,我们经常交换delegate(关键字)、Delegate(类型)和“代表”(概念):) 虽然通常,如果你看到 Delegate 大写,它是指System.Delegate 输入但并非总是如此。

标签: c#


【解决方案1】:

Lambda 本身不是代表。但是,就像您引用的文本一样,它们可用于创建委托:

form.Invoke(new Action(() => AMethod(form)));

【讨论】:

    【解决方案2】:

    是的,lambdas 用于创建委托,但它们本身不是委托。这里的主要问题是 lambda 没有签名,它们的参数列表和返回类型是根据它们所在的上下文确定的。当您将 lambda 放置在需要特定定义的委托实例的地方时,编译器就会知道什么签名 lambda 必须匹配才能有效。

    另一方面,Invoke 不采用某些特定的委托类型,它采用没有任何签名的 Delegate 实例。您需要将您的 lambda 包装在 new SomeActualDelegateType(...) 中(Action 是这里某些代表的常见选择,但不是唯一的选择),以便给它一个实际的签名。

    【讨论】:

      【解决方案3】:

      尝试创建Action:form.Invoke(new Action(() => MyMethod(form)));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-30
        • 2015-03-06
        • 1970-01-01
        • 1970-01-01
        • 2012-08-27
        相关资源
        最近更新 更多