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
compiledFounction.Invoke(10);
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.