Strange behavior of DLR. I have a method accepts two arguments: dynamic and Func<>. When I pass only dynamic OR only Func<> - no errors. But when I try to pass these arguments at same time - appears error "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 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)
{
}
Why it happens?
Of course I can make explicit casting, and error go away:
Method3(d, (Func<string, int>)(f => 1));
But it is uncomfortably. The compiler knows type of lambda, why it requires casting?
In 2010, the Dynamic Type was introduced and that gave us the ability to create dynamic lambda expressions.
No, there isn't. Lambda expressions are optimised (in terms of syntax) for the single parameter case. I know that the C# team feels your pain, and have tried to find an alternative. Whether there ever will be one or not is a different matter.
Have done some research and read through some of the IL generated by the compiler for each of your cases.
This seems to be a limitation in the flexibility of dynamic compilation. Because your method takes a dynamic parameter, the entire call, now becomes a dynamic operation. This means that all of the parameters are late bound, so the processing of the parameters goes through a different processing path during compilation than for parameters not participating in a dynamic operation.
Clearly, as your call to Method2 demonstrates, the compiler has the ability to infer that your intent is for f => 1 to be treated as a Func<string,int>.
However, it looks like this functionality, probably because of the complexity of building out the dynamic call-site, is not yet supported in dynamic compilation.
This is one of those cases where Microsoft is not yet supporting a feature, but may add it in the future.
For now it looks like you have no choice but to give the compiler a hint.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With