views:

88

answers:

3

I've created a lambda expression at runtime, and want to evaluate it - how do I do that? I just want to run the expression by itself, not against any collection or other values.

At this stage, once it's created, I can see that it is of type Expression<Func<bool>>, with a value of {() => "MyValue".StartsWith("MyV")}.

I thought at that point I could just call var result = Expression.Invoke(expr, null); against it, and I'd have my boolean result. But that just returns an InvocationExpression, which in the debugger looks like {Invoke(() => "MyValue".StartsWith("MyV"))}.

I'm pretty sure I'm close, but can't figure out how to get my result!

Thanks.

+9  A: 

Try compiling the expression with the Compile method then invoking the delegate that is returned:

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();
    }
}
Andrew Hare
Thanks, exactly what I was missing. And clearly explained too :)
Marcus
@Marcus - Glad to help!
Andrew Hare
Just a little bit of syntactic sugar. You can replace last two lines with just one:Boolean result = expression.Compile()();
Alexandra Rusina
+1  A: 

As Andrew mentioned, you have to compile an Expression before you can execute it. The other option is to not use an Expression at all, which woul dlook like this:

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

In this example, the lambda expression is compiled when you build your project, instead of being transformed into an expression tree. If you are not dynamically manipulating expression trees or using a library that uses expression trees (Linq to Sql, Linq to Entities, etc), then it can make more sense to do it this way.

Chris
In this instance I am dynamically creating the expression tree, so will need to compile at runtime. Thanks though.
Marcus
+1  A: 

The way I would do it is lifted right from here: MSDN example

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

Also if you want to use an Expression<TDelegate> type then this page: Expression(TDelegate) Class (System.Linq.Expression) has the following example:

// 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
*/
Matt Ellen