You cannot execute an expression tree without compiling it first because expression trees serve a different purpose: they work as flexible blueprints for executable code, rather than being the the executable code itself (with is rather inflexible).
An expression tree is a data structure that describes code (compiled or not) at an abstraction level that is higher than the code itself. Unlike code, the data structure can be manipulated to make a different structure that describes some other piece of code. Unlike the data structure, the code can be evaluated to produce a result.
Consider this example:
Expression p1 = Expression.Parameter(typeof(int), "a");
Expression p2 = Expression.Parameter(typeof(int), "b");
Expression expr = Expression.Add(p1, p2);
It shows an expression expr
being created, describing a simple expression tree a+b
. At this point, we have a tree-like data structure with three nodes - two nodes representing parameters, and one node representing addition. We can do lots of things with the expression tree, such as examining its content, finding its return type, and so on. We can even manipulate its structure to make other expressions based on it: for example, we could add a third parameter, and make a+b+c
, like this:
Expression p3 = Expression.Parameter(typeof(int), "c");
expr = Expression.Add(expr, p3);
One thing we cannot do, however, is pass it two integer values and obtain their sum: expression trees do not provide methods for evaluating them. In order to do that, you need real code, not a description of code.
Expression trees provide a way to convert descriptions of code into code by way of compiling them. Once you make an expression tree into lambda and call the Compile()
method on it, you get back a compiled CIL code that looks like this:
ldarg.0
ldarg.1
add
ret
This code can be passed two values for evaluation, and it will return the sum to you. However, some information is lost in translation: specifically, the names of parameters a
and b
are no longer there in the compiled code: they are not necessary to perform calculations, so they have been eliminated.