无法将动态参数和lambda传递给方法

Sto*_*m34 14 c# lambda dynamic

DLR的奇怪行为.我有一个方法接受两个参数:dynamic和Func <>.当我只传递动态OR只有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)
    {
    }
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

当然我可以进行明确的转换,并且错误消失了:

Method3(d, (Func<string, int>)(f => 1));
Run Code Online (Sandbox Code Playgroud)

但令人不安的是.编译器知道lambda的类型,为什么需要转换?

Ayo*_*o I 6

做了一些研究,并阅读了编译器为每个案例生成的一些IL.

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

显然,正如您对Method2的调用所示,编译器能够推断您的f => 1的意图被视为Func <string,int>.

但是,动态编译中尚不支持此功能,可能是因为构建动态调用站点的复杂性.

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

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