Sunday, June 21, 2009

Lambda Expression Tree

Lambda expression is parsed as tree under the hood. The lambda expression is parsed and stored as tree-shaped structure. Each node in the expression tree is represented as expression. System.Linq.Expressions.Expression class contains static factory methods that can be used to build and manipulate expression tree. The following figure shows how a simple expression is parsed and represented.


As the above figure shows, the expression is represented with two parameters: Body and Parameters. We had two parameters in the image above. Each parameter is of type Expression (ParameterExpression). FYI, there are several types of expressions(BinaryExpression, ConditionalExpression, ConstantExpression etc) that is derived from base Expression class. Also, Body is of type Binary Expression. So lets take an expression and dissect it.

Analyzing an Expression Tree

ay we have a function representing delegate  Func<int, bool>. The expression is:

Expression<Func<int, bool>> expressionTree =(i => i> 5);  

The expression has subparts that has shown in the image below


Here in the above statement we see the lambda expression takes an integer value and check if the value is greater than 5 or not and return a boolean value. The above expreesionTree variable's two property we have used in the code below. One is parameters collection and another one is Body. Parameters collection is of length one as we have only one parameter i

//This is i before the lambda expression

ParameterExpression param = expressionTree.Parameters[0] as ParameterExpression;

//this is the body of the expression, right side of lambda operator (=>). i.e., i>5

BinaryExpression  body=expressionTree.Body as BinaryExpression;

//This is the the i in the body. I.e., i on the left side of greater than

ParameterExpression left = body.Left as ParameterExpression;

//This is the constant in the body. That is 5

ConstantExpression right = body.Right as ConstantExpression;

Console.WriteLine("Docomposed Expression: {0} => {1} {2} {3}", param.Name, left.Name, body.NodeType, right.Value);

Building an Expression Tree

We can build the same expression tree that we have seen in above (for expression i=>i<5). All we need to do to generate different expressions (BinaryExpression, ConditionalExpression,ConstantExpression etc) and combine these properly into a single expression. Finally we need to compile and invoke the expression. A shown in the code snippet below, we can use Expression static methods to generate various types of expressions. we can generate a full function from that expression with Expression.Lambda method.


//bulild the prarameter expression

ParameterExpression param=Expression.Parameter(typeof(int),"i");

//build the constant expression

ConstantExpression constant = Expression.Constant(5, typeof(int));

//build the binary expression

BinaryExpression numLessThanAndEqual = Expression.LessThanOrEqual(param, constant);

//build the whole expression. that is body

Expression<Func<int, bool>> func = Expression.Lambda<Func<int, bool>>(numLessThanAndEqual, new ParameterExpression[] {param });

//complile the expression

Func<int,bool> compiledFounction = func.Compile();

//invoke the expression




No comments:

Post a Comment