No se puede inicializar LambdaExpression con una expresión

c# expression-trees lambda

Pregunta

Pregunta similar a la de John K , pero más específica y la respuesta aceptada no se ajusta a mis necesidades.

Esto compila bien:

Expression<Func<object, object>> specificExpression = (object o) => new object();
Expression generalExpression = specificExpression;

Y este no lo hace:

Expression generalExpression = (object o) => new object();

Error de compilación informado:

Cannot convert lambda expression to type 'System.Linq.Expressions.Expression' because it is not a delegate type

Expression<Func<T1,T2>> deriva de la Expression .

Ahora tengo un marco con métodos que aceptan todo tipo de expresiones, es decir, escriba Expression . Ser forzado a lanzar explícitamente lambdas a la Expression<Func<T1,T2>> correspondiente Expression<Func<T1,T2>> en cada llamada de método es frustrante.

¿Alguna buena razón por la que este comportamiento básico de OOP se rompe en este caso?

Respuesta aceptada

La conversión no funciona porque el compilador no puede inferir qué tipo de expresión específica está intentando crear. ¿Y si hicieras esto?

Expression generalExpression = (object o) => "foo";

¿Debería ser una Expression<Func<object, string>> ? ¿Qué pasa con Expression<Func<object, object>> o Expression<Func<object, IComparable>> ? Todos estos tipos serían un tipo final válido para el árbol de expresiones, y el compilador no pretende saber lo que está tratando de hacer.

Debe pasar por el tipo específico para informar al compilador qué tipo de expresión desea producir:

Expression generalExpression = (Expression<Func<object, object>>)
    (object o) => new object();

Vería un error de compilador similar si intentara esto:

Delegate generalDelegate = delegate() { };

¿Es eso una Action , un ThreadStart o algún otro tipo de delegado que devuelve el vacío sin argumentos?


Respuesta popular

El compilador de C # evalúa la expresión a la forma menos compleja, por ejemplo:

 var x = (object o) => new object();

x debe ser un Func<object, object> , no una Expression<Func<object, object>> . En este caso, el compilador está determinando que el valor es un delegado, y dado que Expression no puede tomar un delegado (solo los tipos Expression<Func<>> / Expression<Action> pueden), se produce el error del compilador.

También, vea la respuesta de @Riana, porque la forma de la expresión es reescrita por el compilador.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow