DLR的奇怪行为。 我有一个方法接受两个参数:dynamic和Func<&gt ;.当我只传递动态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)
{
}
为什么会这样?
当然我可以进行明确的投射,错误就会消失:
Method3(d, (Func<string, int>)(f => 1));
但令人不安的是。编译器知道lambda的类型,为什么需要转换?
答案 0 :(得分:6)
已完成一些研究并阅读编译器为您的每个案例生成的一些IL。
这似乎是动态编译灵活性的限制。因为您的方法采用动态参数,所以整个调用现在变为动态操作。这意味着所有参数都是后期绑定的,因此在编译期间参数的处理通过不同于未参与动态操作的参数的处理路径。
显然,正如您对Method2的调用所示,编译器能够推断您的意图是针对f =&gt; 1被视为Func&lt; string,int&gt;。
但是,动态编译尚不支持此功能,可能是因为构建动态调用站点的复杂性。
这是Microsoft尚未支持某项功能的情况之一,但可能会在将来添加该功能。
现在看起来你别无选择,只能给编译器一个提示。