Reverso de Expresión > .Compile ()?

.net c# expression-trees lambda linq

Pregunta

Como podemos:

Expression<Func<int, bool>> predicate = x => x > 5;
var result = Enumerable.Range(0,10).Where(predicate.Compile());

Cómo puedo:

Func<int,bool> predicate = x => x > 5;
Expression<Func<int,bool>> exp = predicate.Decompile();

Es decir, quiero obtener la Expression correspondiente del Func . ¿Es posible?

Respuesta aceptada

No hay un Decompile() mágico para una instancia delegada , a menos que se deconstruya el IL (quizás con mono.cecil). Si desea un árbol de expresiones, tendrá que comenzar con un árbol de expresiones, así que tenga Expression<Func<int, bool>> througout.

Como un caso de borde, puede obtener información del delegado del método básico de .Method (the MethodInfo ) y .Target (the arg0 ) del arg0 ; sin embargo, para la mayoría de los escenarios que involucran un método lambda o anónimo, esto apuntará al método de generación de compiladores en La clase de captura, así que realmente no te ayudará mucho. Está bastante limitado a escenarios como:

Func<string,int> parse = int.Parse;

Respuesta popular

Pase el lambda a un método que acepte una expresión <> y el compilador de C # le pasará un árbol de expresiones en tiempo de ejecución. Sin embargo, esto solo funciona si pasa la lambda directamente, no si intenta pasar una instancia delegada creada desde una lambda.

var exp = Decompile(x => x > 5);

public Expression<Func<int, bool>> Decompile(Expression<Func<int, bool>> exp)
{
    return exp;
}

La opción más cercana que he encontrado para descompilar una instancia de delegado se detalla en esta publicación del blog de Jean-Baptiste Evain, que trabaja en el equipo Mono . Utiliza el excelente proyecto Mono.Cecil para descompilar el IL en un AST personalizado, luego lo mapea lo mejor posible en las expresiones LINQ.



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