Extraño comportamiento de DLR. Tengo un método que acepta dos argumentos: dinámico y Func<>. Cuando paso solo dinámico O solo Func<> - no hay errores. Pero cuando trato de pasar estos argumentos al mismo tiempo, aparece el error "No se puede usar una expresión lambda como argumento para una operación enviada dinámicamente sin convertirla primero en un delegado o tipo de árbol de expresión".
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) { }¿Por qué sucede?
Por supuesto, puedo hacer una conversión explícita y el error desaparece:
Method3(d, (Func<string, int>)(f => 1));Pero es incómodo. El compilador conoce el tipo de lambda, ¿por qué requiere conversión?
Investigué un poco y leí algunos de los IL generados por el compilador para cada uno de sus casos.
Esto parece ser una limitación en la flexibilidad de la compilación dinámica. Debido a que su método toma un parámetro dinámico, la llamada completa ahora se convierte en una operación dinámica. Esto significa que todos los parámetros están vinculados en tiempo de ejecución, por lo que el procesamiento de los parámetros pasa por una ruta de procesamiento diferente durante la compilación que para los parámetros que no participan en una operación dinámica.
Claramente, como demuestra su llamada a Method2, el compilador tiene la capacidad de inferir que su intención es que f => 1 sea tratado como Func<string,int>.
Sin embargo, parece que esta funcionalidad, probablemente debido a la complejidad de construir el sitio de llamadas dinámicas, aún no es compatible con la compilación dinámica.
Este es uno de esos casos en los que Microsoft aún no admite una característica, pero puede agregarla en el futuro.
Por ahora, parece que no tiene más remedio que darle una pista al compilador.