Получение результата из выражения - PullRequest
7 голосов
/ 06 декабря 2009

Я создал лямбда-выражение во время выполнения и хочу оценить его - как мне это сделать? Я просто хочу запустить выражение самостоятельно, а не для какой-либо коллекции или других значений.

На этом этапе, после его создания, я вижу, что он имеет тип Expression<Func<bool>> со значением {() => "MyValue".StartsWith("MyV")}.

Я подумал, что в этот момент я могу просто позвонить var result = Expression.Invoke(expr, null); против него, и я получу свой логический результат. Но это просто возвращает InvocationExpression, который в отладчике выглядит как {Invoke(() => "MyValue".StartsWith("MyV"))}.

Я почти уверен, что я близко, но не могу понять, как получить мой результат!

Спасибо.

Ответы [ 3 ]

15 голосов
/ 06 декабря 2009

Попробуйте скомпилировать выражение с помощью метода Compile, затем вызовите возвращаемый делегат:

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();
    }
}
2 голосов
/ 06 декабря 2009

Как упоминал Эндрю, вы должны скомпилировать выражение, прежде чем сможете его выполнить. Другой вариант - вообще не использовать выражение, которое выглядит следующим образом:

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

В этом примере лямбда-выражение компилируется при сборке проекта, а не преобразуется в дерево выражений. Если вы не динамически манипулируете деревьями выражений или не используете библиотеку, которая использует деревья выражений (Linq to Sql, Linq to Entities и т. Д.), Тогда может иметь смысл сделать это следующим образом.

1 голос
/ 06 декабря 2009

Способ, которым я бы это сделал, поднят прямо отсюда: Пример MSDN

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

Также, если вы хотите использовать тип Expression<TDelegate>, эта страница: Класс выражений (TDelegate) (System.Linq.Expression) имеет следующий пример:

// 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
*/
...