2009-12-06 13 views
7

Stworzyłem wyrażenie lambda w czasie wykonywania i chcę go ocenić - jak to zrobić? Po prostu chcę uruchomić wyrażenie samodzielnie, a nie przeciwko jakiejkolwiek kolekcji lub innym wartościom.Uzyskiwanie wyniku Wyrażenie

Na tym etapie, po utworzeniu, widzę, że jest on typu Expression<Func<bool>>, o wartości {() => "MyValue".StartsWith("MyV")}.

Pomyślałem, że w tym momencie mogę po prostu zadzwonić pod numer var result = Expression.Invoke(expr, null);, a otrzymam wynik boolowski. Ale to po prostu zwraca InvocationExpression, który w debugerze wygląda jak {Invoke(() => "MyValue".StartsWith("MyV"))}.

Jestem prawie pewna, że ​​jestem blisko, ale nie mogę wymyślić, jak uzyskać mój wynik!

Dzięki.

Odpowiedz

14

Spróbuj kompilacji wyrażenia z metodą Compile następnie wywoływanie delegata, który jest zwracany:

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

Thanks dokładnie to, czego mi brakowało. I jasno wytłumaczone też :) – Marcus

+0

@Marcus - Chętnie pomogę! –

+0

Tylko odrobina cukru syntaktycznego. Możesz zastąpić dwie ostatnie linie tylko jedną: Wynik Boolean = expression.Compile()(); –

2

Jak wspomniano Andrew, musisz skompilować Expression, zanim będzie można go wykonać. Inną opcją jest nie użyć wyrażenia w ogóle, co polecałbym dlook tak:

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

W tym przykładzie wyrażenie lambda jest kompilowany podczas budowania projektu, zamiast być przekształcona w drzewie ekspresji. Jeśli nie manipulujesz dynamicznie drzewkami wyrażeń lub korzystasz z biblioteki korzystającej z drzewek wyrażeń (Linq to Sql, Linq to Entities, itp.), To może mieć więcej sensu robienie tego w ten sposób.

+0

W tym przypadku dynamicznie tworzę drzewo wyrażeń, więc będę musiał skompilować je w czasie wykonywania. W każdym razie dzięki. – Marcus

1

Sposób zrobiłbym to jest zniesione prawo stąd: MSDN example

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

Także jeśli chcesz użyć typ Expression<TDelegate> następnie tę stronę: Expression(TDelegate) Class (System.Linq.Expression) ma następujący przykład:

// 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 
*/ 
Powiązane problemy