me falta lo obvio: ¿Cómo se accede al valor de un parámetro dentro de un árbol de expresión expresión lambda?obtener el valor de tiempo de ejecución de un ParameterExpression en un árbol de expresión
Escenario: Para un delegado x I crear dinámicamente una expresión lambda con un cuerpo de árbol de expresión que tiene la misma firma que el delegado x. Dentro del cuerpo del lamdba, realizo algunas tareas de validación, comprobación, registro (esto es solo código de prueba, no producción), y luego invoco el delegado x original con los parámetros originales. Si el delegado tiene un valor de retorno, esto también se devuelve.
que funciona bastante bien (incluyendo la aprobación de los parámetros para el delegado original).
Pero estoy golpeando una pared de ladrillos si quiero acceder a los valores de los parámetros originales pasan a la delegado/lambda.
seudo código:
var del = new Func<string, int>(_=> {return 42;});
var paramDefs = Array.ConvertAll<ParameterInfo, ParameterExpression>(del.Method.GetParameters(), _ => { return Expression.Parameter(_.ParameterType, _.Name); });
var variableTest = Expression.Variable(typeof(string), "str");
var expression = Expression.Block(
new [] { variableTest },
// this line assigns the actual run time value (which is what I need) of the parameter to the variable - but I cannot hardcode the index.
//Expression.Assign(variableTest, paramDefs[0])
// this line would assigns the ParameterExpression object (causing a run-time exception since the type of the variable is string) ... I need the _value_ of the first (or nth) parameter.
Expression.Assign(variableTest, Expression.ArrayIndex(Expression.Constant(paramDefs), Expression.Constant(0)))
);
var lamdba = Expression.Lambda(del.GetType(), expression, "foo", paramDefs);
var del2 = lamdba.Compile() as Func<string, int>;
del2("this is a test");
Parece que el código comentado es correcto, así que lo haría. Usted dice que no puede codificar el índice. Por qué no? Me parece que eso funcionaría bien. –
Desde entonces he cambiado el código. Inicialmente quise recorrer los paramDefs en el árbol de expresiones (Expression.Loop), visitando cada parámetro uno por uno. Dado que el código funciona en cualquier tipo de delegado, la codificación difícil del índice no habría funcionado. Saqué la construcción de bucle del árbol de expresiones. Para un delegado con 5 parámetros, ahora simplemente genero cinco expresiones (el caso más simple es copiar cada valor de parámetro a un objeto []). Sin embargo, la pregunta inicial todavía me molesta: ¿hay alguna forma de obtener el valor real de una instancia de ParameterExpression? – dalo