Durante il mio lavoro con gli alberi di espressione per alcuni giorni, mi sono imbattuto in qualcosa che trovo difficile da capire; si spera che qualcuno sarà in grado di fare un po 'di luce qui.Come creare un'espressione <Func <dynamic, dynamic >> - Oppure è un bug?
Se si codifica Expression<Func<dynamic, dynamic>> expr1 = x => 2 * x;
il compilatore si lamenterà e non si otterrà da nessuna parte. Tuttavia, lo sembra che sia che se si crea un'espressione di questo tipo tramite un metodo, il compilatore sembra essere soddisfatto e l'app risultante funziona. Questo non ha senso, quindi mi sto chiedendo cosa succede dietro le tende.
Suppongo che, sotto il cofano, l'espressione restituito da ConvertExpression
è forse di tipo Expression<Func<object, object>>
, che è un tipo valido, ma mi lascia perplesso che non posso usare Expression<Func<dynamic, dynamic>>
tipo in una dichiarazione, eppure posso usarlo come il tipo di ritorno di un metodo. Guarda un esempio qui sotto.
Grazie mille!
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;
}
}
Dynamics in Expression Trees - Soluzione qui: [http://stackoverflow.com/questions/3562088/c-4-dynamic-in-expression-trees](http://stackoverflow.com/questions/3562088/c -4-dynamic-in-expression-trees) –