【问题标题】:Can not pass dynamic argument and lambda to the method无法将动态参数和 lambda 传递给方法
【发布时间】:2015-06-27 14:17:47
【问题描述】:

DLR 的奇怪行为。 我有一个方法接受两个参数:动态和 Func。当我只通过动态或仅 Func - 没有错误。但是当我尝试同时传递这些参数时 - 出现错误“不能使用 lambda 表达式作为动态调度操作的参数,而无需先将其转换为委托或表达式树类型。”:

    static void Main(string[] args)
    {
        dynamic d = 1;

        Method1(d);// - OK
        Method2(f => 1);// - OK
        Method3(d, f => 1);// - Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.
    }

    static void Method1(dynamic d)
    {
    }

    static void Method2(Func<string, int> func)
    {
    }

    static void Method3(dynamic d, Func<string, int> func)
    {
    }

为什么会这样?

当然我可以进行显式转换,并且错误消失:

Method3(d, (Func<string, int>)(f => 1));

但这很不舒服。编译器知道 lambda 的类型,为什么需要强制转换?

【问题讨论】:

标签: c# dynamic lambda


【解决方案1】:

已经完成了一些研究并通读了编译器为您的每个案例生成的一些 IL。

这似乎是对动态编译灵活性的限制。因为您的方法采用动态参数,所以整个调用现在变成了动态操作。这意味着所有参数都是后期绑定的,因此在编译期间参数的处理与不参与动态操作的参数的处理路径不同。

显然,正如您对 Method2 的调用所示,编译器能够推断出您的意图是将 f => 1 视为 Func

但是,动态编译似乎还不支持此功能,可能是因为构建动态调用站点的复杂性。

这是 Microsoft 尚不支持某项功能但可能会在未来添加该功能的情况之一。

现在看来你别无选择,只能给编译器一个提示。

【讨论】:

    猜你喜欢
    • 2013-10-08
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多