Durante mi trabajo con árboles de expresión durante unos días, me encontré con algo que encuentro difícil de entender; con suerte alguien podrá así arrojar algo de luz aquí.Cómo crear una expresión <Func <dynamic, dynamic >> - ¿O es un error?
Si codifica Expression<Func<dynamic, dynamic>> expr1 = x => 2 * x;
, el compilador se quejará y no obtendrá nada. Sin embargo, parece que si crea una expresión de este tipo a través de un método, entonces el compilador parece estar contento con él y la aplicación resultante funciona. Esto no tiene sentido, así que me pregunto qué sucede detrás de las cortinas.
supongo que, bajo el capó, la expresión devuelta por ConvertExpression
es quizás el tipo de Expression<Func<object, object>>
, que es un tipo válido, pero me extraña que no puedo usar Expression<Func<dynamic, dynamic>>
tipo en una declaración y todavía lo puedo usar como el tipo de devolución de un método. Vea un ejemplo a continuación.
¡Muchas gracias!
public class ExpressionExample
{
public void Main()
{
// Doesn't compile:
//Expression<Func<dynamic, dynamic>> expr1 = x => 2 * x;
// Compiles and works - OK
Expression<Func<double, double>> expr2 = x => 2 * x;
Func<double, double> func2 = (Func<double, double>)expr2.Compile();
Console.WriteLine(func2(5.0).ToString()); // Outputs 10
// Compiles and works - ??? This is the confusing block...
Expression<Func<dynamic, dynamic>> expr3 = ConvertExpression(expr2);
Func<dynamic, dynamic> func3 = (Func<dynamic, dynamic>)expr3.Compile();
Console.WriteLine(func3(5.0).ToString()); // Outputs 10
// Side note: compiles and works:
Expression<Func<object, object>> expr4 = x => double.Parse(2.ToString()) * double.Parse(x.ToString());
Func<object, object> func4 = (Func<object, object>)expr4.Compile();
Console.WriteLine(func4(5.0).ToString()); // Outputs 10
}
private Expression<Func<dynamic, dynamic>> ConvertExpression<TInput, TOutput>(Expression<Func<TInput, TOutput>> expression)
{
Expression<Func<object, TInput>> convertToInput = value => (TInput)value;
// The following doesn't compile: var input = Expression.Parameter(typeof(dynamic), "input");
var input = Expression.Parameter(typeof(object), "input");
Expression<Func<TOutput, dynamic>> convertToOutput = value => (dynamic)value;
var body = Expression.Invoke(convertToOutput, Expression.Invoke(expression, Expression.Invoke(convertToInput, input)));
var lambda = Expression.Lambda<Func<dynamic, dynamic>>(body, input);
return lambda;
}
}
Dinámica en Expression Trees - Solución aquí: [http://stackoverflow.com/questions/3562088/c-4-dynamic-in-expression-trees](http://stackoverflow.com/questions/3562088/c -4-dynamic-in-expression-trees) –