日期:2014-05-17  浏览次数:21009 次

c# - expression tree and lambda - serie 1

In this post, we are going to discuss the topic on the Expression Tree and Delegate and Lambda, we are going to go through from simple expresison, then expression converted to delegate (lambda), and then we shape up/build up to a more complicated Expression Tree example and we compare it with its equivalent Lambda expression, later we shows why behind Expression Tree since we have the lambda expresion which has hte nice compile time check.

Code as Data

Code as Data is a long existed idea. But it hasn't bee used much in popular programming language. Expression Tree in .NET provides an abstract way of representing the code as a tree of objects. It's like COdeDOM but operate at a slightly higher level. The primary use of Expression tree is in LINQ and you can custom Expression to enable code execution in another end (or even language)

?

Expression Trees

The namespace in question is "System.Linq.Expression" , of all the classes that is contained in this namespace, Expression is the one that you may use most.?

?

Build a ?simple expression tree

Let's first see an simple example of Building a exprssion tree

?

public static void ExploratoryExample()
    {
      Expression firstArg = Expression.Constant(2);
      Expression secondArg = Expression.Constant(3);
      Expression add = Expression.Add(firstArg, secondArg);
      Console.WriteLine(add); // this will evaluation the expression tree and does not execute the expression treee, it will print some string representation of the Linq Expression Tree 
                              // something like (1 + 2)
      
    }
?

It does almost trivial, it creates two Constant Expression and then made a call Expresion to glue the two together, Graphical representaion is as follow

?



?

In the Expression class, there are two properties?

Type: the .NET type of the evaluated Expression

NodeType: returns the kind of expression represented , as a member of ExpressoinType enumeration,with values such as LessThan....


?As you already know, we have build the ExpressionTree, but we can do barely anything with it, except, Expression has a Compile method which will turnst the Tree representaion of the expresion into executable code piece - a delegate. ?Below shows how.

?

?

    public static void ExploratoryExample()
    {
      // build expression tree as above
      // ...
      Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile(); // Lambda expression can compiled, and once compiled 
                                                                        // you can execute it 
      Console.WriteLine("compiled() = {0}", compiled());
    }

?

Now, you will get 5 if you execute the compiled delegate (Func<T> in this case)...

Converting a expression to a expression tree

So this is the other way around of the conversion, and it has ?a lot of use implicaiton, suppose that you have some code (which is static checked and compiled by the Compiler) and you can convert that readily to expression tree.?

?

A very eimple way of doing that is as follow?

?

?

      // initialize a expression with a delegate
      // initialization as the conversion
      Expression<Func<int>> returns5 = () => 5;
      // you can compile the Expression back to lambda/delegate, as before 
      Func<int> compiled = returns5.Compile();
      Console.WriteLine("compiled() = {0}", compiled());

However, the conversion has limitation. In example?

?

?

  • You cannot convert a block of statement (even just one return statement), only single expression