2009-12-06 11 views
7

He creado una expresión lambda en el tiempo de ejecución y quiero evaluarla, ¿cómo puedo hacer eso? Solo quiero ejecutar la expresión por sí mismo, no en contra de ninguna colección u otros valores.Obteniendo el resultado de una Expresión

En esta etapa, una vez que se ha creado, puedo ver que es del tipo Expression<Func<bool>>, con un valor de {() => "MyValue".StartsWith("MyV")}.

Pensé que en ese momento podría llamar al var result = Expression.Invoke(expr, null); y tendría mi resultado booleano. Pero eso solo devuelve un InvocationExpression, que en el depurador se parece a {Invoke(() => "MyValue".StartsWith("MyV"))}.

Estoy bastante seguro de que estoy cerca, ¡pero no puedo entender cómo obtener mi resultado!

Gracias.

Respuesta

14

tratar de compilar la expresión con el método Compile continuación, invocando el delegado que se devuelve:

using System; 
using System.Linq.Expressions; 

class Example 
{ 
    static void Main() 
    { 
     Expression<Func<Boolean>> expression 
       =() => "MyValue".StartsWith("MyV"); 
     Func<Boolean> func = expression.Compile(); 
     Boolean result = func(); 
    } 
} 
+0

Gracias , exactamente lo que me estaba perdiendo Y claramente explicado también :) – Marcus

+0

@Marcus - ¡Me alegra ayudar! –

+0

Solo un poco de azúcar sintáctico. Puede reemplazar las dos últimas líneas con solo una: Boolean result = expression.Compile()(); –

2

Como se mencionó Andrew, debe compilar una expresión antes de poder ejecutarlo. La otra opción es no utilizar una expresión en absoluto, que Woul dlook así:

Func<Boolean> MyLambda =() => "MyValue".StartsWith("MyV"); 
var Result = MyLambda(); 

En este ejemplo, la expresión lambda se compila cuando se genera el proyecto, en lugar de ser transformado en un árbol de expresión. Si no está manipulando árboles de expresión dinámicamente o utilizando una biblioteca que utiliza árboles de expresión (Linq a Sql, Linq a entidades, etc.), entonces puede tener más sentido hacerlo de esta manera.

+0

En esta instancia, estoy creando dinámicamente el árbol de expresiones, por lo que necesitaré compilar en tiempo de ejecución. Gracias sin embargo. – Marcus

1

La forma en que lo haría es levantada desde aquí: MSDN example

delegate int del(int i); 
static void Main(string[] args) 
{ 
    del myDelegate = x => x * x; 
    int j = myDelegate(5); //j = 25 
} 

Además, si desea utilizar un tipo de Expression<TDelegate> entonces esta página: Expression(TDelegate) Class (System.Linq.Expression) tiene el siguiente ejemplo:

// Lambda expression as executable code. 
Func<int, bool> deleg = i => i < 5; 
// Invoke the delegate and display the output. 
Console.WriteLine("deleg(4) = {0}", deleg(4)); 

// Lambda expression as data in the form of an expression tree. 
System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5; 
// Compile the expression tree into executable code. 
Func<int, bool> deleg2 = expr.Compile(); 
// Invoke the method and print the output. 
Console.WriteLine("deleg2(4) = {0}", deleg2(4)); 

/* This code produces the following output: 
    deleg(4) = True 
    deleg2(4) = True 
*/ 
Cuestiones relacionadas