Chapter90:ExpressionTrees

No Comments

Parameter                                     Details

TDelegate                    Thedelegatetypetobeusedfortheexpression

lambdaExpression Thelambdaexpression(ex.num=>num<5)

ExpressionTreesareExpressionsarrangedinatreelikedatastructure.Eachnodeinthetreeisarepresentationof an expression, an expression being code. An In-Memory representation of a Lambda expression would be an Expression tree, which holds the actual elements (i.e. code) of the query, but not its result. Expression trees make the structure of a lambda expression transparent and explicit.

Section90.1:CreateExpressionTreeswithalambda expression

Followingismostbasicexpressiontreethatiscreatedbylambda.

Expression<Func<int,bool>>lambda=num=>num==42;

To create expression trees ‘by hand’, one should use Expressionclass. Expression above would be equivalent to:

ParameterExpressionparameter=Expression.Parameter(typeof(int),”num”);//numargument ConstantExpressionconstant=Expression.Constant(42,typeof(int));//42constant BinaryExpressionequality=Expression.Equals(parameter,constant);//equalityoftwoexpressions (num==42)

Expression<Func<int,bool>>lambda=Expression.Lambda<Func<int,bool>>(equality,parameter);

Section90.2:CreatingExpressionTreesbyUsingtheAPI

usingSystem.Linq.Expressions;

//Manuallybuildtheexpressiontreefor

//thelambdaexpressionnum=>num<5.

ParameterExpressionnumParam=Expression.Parameter(typeof(int),”num”); ConstantExpressionfive=Expression.Constant(5,typeof(int)); BinaryExpressionnumLessThanFive=Expression.LessThan(numParam,five); Expression<Func<int,bool>>lambda1=

Expression.Lambda<Func<int,bool>>( numLessThanFive,

newParameterExpression[]{numParam});

Section90.3:CompilingExpressionTrees

//Defineanexpressiontree,takinganinteger,returningabool.

Expression<Func<int,bool>>expr=num=>num<5;

//CalltheCompilemethodontheexpressiontreetoreturnadelegatethatcanbecalled.

Func<int,bool>result=expr.Compile();

//Invokethedelegateandwritetheresulttotheconsole.

Console.WriteLine(result(4));//Printstrue

//PrintsTrue.

//Youcanalsocombinethecompilestepwiththecall/invokestepasbelow:

Console.WriteLine(expr.Compile()(4));

Section90.4:ParsingExpressionTrees

usingSystem.Linq.Expressions;

//Createanexpressiontree.

Expression<Func<int,bool>>exprTree=num=>num<5;

//Decomposetheexpressiontree.

ParameterExpressionparam=(ParameterExpression)exprTree.Parameters[0];

BinaryExpressionoperation=(BinaryExpression)exprTree.Body;

ParameterExpressionleft=(ParameterExpression)operation.Left;

ConstantExpressionright=(ConstantExpression)operation.Right;

Console.WriteLine(“Decomposedexpression:{0}=>{1}{2}{3}”,

param.Name,left.Name,operation.NodeType,right.Value);

//Decomposedexpression:num=>numLessThan5

Section90.5:ExpressionTreeBasic

Expressiontreesrepresentcodeinatree-likedatastructure,whereeachnodeisanexpression

Expression Trees enables dynamic modification of executable code, the execution of LINQ queries in various databases,andthecreationofdynamicqueries.Youcancompileandruncoderepresentedbyexpressiontrees.

Thesearealsousedinthedynamiclanguagerun-time(DLR)toprovideinteroperabilitybetweendynamiclanguages andthe.NETFrameworkandtoenablecompilerwriterstoemitexpressiontreesinsteadofMicrosoftintermediate language(MSIL).

ExpressionTreescanbecreatedVia

  1. Anonymouslambdaexpression,
  2. ManuallybyusingtheSystem.Linq.Expressionsnamespace.

ExpressionTreesfromLambdaExpressions

WhenalambdaexpressionisassignedtoExpressiontypevariable,thecompileremitscodetobuildanexpression tree that represents the lambda expression.

The following code examples shows how to have the C# compiler create an expression tree that represents the lambda expression num => num < 5.

Expression<Func<int,bool>>lambda=num=>num<5;

ExpressionTreesbyUsingtheAPI

Expression Trees also created using the ExpressionClass. This class contains static factory methods that create expression tree nodes of specific types.

BelowarefewtypeofTreenodes.

  1. ParameterExpression
  2. MethodCallExpression

Thefollowingcode exampleshows howtocreate anexpression treethat representsthelambda expressionnum

=>num<5byusingtheAPI.

ParameterExpressionnumParam=Expression.Parameter(typeof(int),”num”); ConstantExpressionfive=Expression.Constant(5,typeof(int)); BinaryExpressionnumLessThanFive=Expression.LessThan(numParam,five);

Expression<Func<int,bool>>lambda1=Expression.Lambda<Func<int,bool>>(numLessThanFive,new ParameterExpression[] {numParam});

Section 90.6: Examining the Structure of an Expression using Visitor

Definea new visitor classby overriding some ofthe methods ofExpressionVisitor:

classPrintingVisitor:ExpressionVisitor{

protectedoverrideExpressionVisitConstant(ConstantExpressionnode){

Console.WriteLine(“Constant:{0}”,node);

returnbase.VisitConstant(node);

}

protectedoverrideExpressionVisitParameter(ParameterExpressionnode){

Console.WriteLine(“Parameter:{0}”,node);

returnbase.VisitParameter(node);

}

protectedoverrideExpressionVisitBinary(BinaryExpressionnode){ Console.WriteLine(“Binarywithoperator{0}”,node.NodeType);

returnbase.VisitBinary(node);

}

}

CallVisittousethisvisitoronanexistingexpression:

Expression<Func<int,bool>>isBig=a=>a>1000000;

varvisitor=newPrintingVisitor(); visitor.Visit(isBig);

Section90.7:UnderstandingtheexpressionsAPI

We’regoingtousetheexpressiontreeAPItocreateaCalculateSalesTaxtree.InplainEnglish,here’sasummary of the steps it takes to create the tree.

  1. Checkiftheproductis taxable
  2. Ifitis,multiplythelinetotalbytheapplicabletaxrateandreturnthatamount
  3. Otherwisereturn0

//Forreference,we’reusingtheAPItobuildthislambdaexpression

orderLine=>orderLine.IsTaxable?orderLine.Total*orderLine.Order.TaxRate:0;

//TheorderLineparameterwepassintothemethod.                          Wespecifyit’stype(OrderLine)andthenameof theparameter.

ParameterExpressionorderLine=Expression.Parameter(typeof(OrderLine),”orderLine”);

//Check iftheparameter istaxable;                 Firstweneedtoaccessthe istaxableproperty,thencheckif it’strue

PropertyInfoisTaxableAccessor=typeof(OrderLine).GetProperty(“IsTaxable”); MemberExpressiongetIsTaxable=Expression.MakeMemberAccess(orderLine,isTaxableAccessor); UnaryExpressionisLineTaxable=Expression.IsTrue(getIsTaxable);

//Beforecreatingtheif,weneedtocreatethebraches

//Ifthelineistaxable,we’llreturnthetotaltimesthetaxrate;getthetotalandtaxrate,thenmultiply

//Getthetotal

PropertyInfototalAccessor=typeof(OrderLine).GetProperty(“Total”);MemberExpressiongetTotal=Expression.MakeMemberAccess(orderLine,totalAccessor);

//Gettheorder

PropertyInfoorderAccessor=typeof(OrderLine).GetProperty(“Order”);MemberExpressiongetOrder=Expression.MakeMemberAccess(orderLine,orderAccessor);

//Getthetaxrate-noticethatwepassthegetOrderexpressiondirectlytothememberaccess

PropertyInfotaxRateAccessor=typeof(Order).GetProperty(“TaxRate”);MemberExpressiongetTaxRate=Expression.MakeMemberAccess(getOrder,taxRateAccessor);

//Multiplythetwo-noticewepassthetwooperandexpressionsdirectlytomultiply

BinaryExpressionmultiplyTotalByRate=Expression.Multiply(getTotal,getTaxRate);

//Ifthelineisnottaxable,we’llreturnaconstantvalue-0.0(decimal)

ConstantExpressionzero=Expression.Constant(0M);

//Createtheactualifcheckandbranches

ConditionalExpressionifTaxableTernary=Expression.Condition(isLineTaxable, multiplyTotalByRate,zero);

//Wrapthewholethingupina”method”-aLambdaExpression

Expression<Func<OrderLine,decimal>>method=Expression.Lambda<Func<OrderLine,

decimal>>(ifTaxableTernary,orderLine);

About us and this blog

We are a digital marketing company with a focus on helping our customers achieve great results across several key areas.

Request a free quote

We offer professional SEO services that help websites increase their organic search score drastically in order to compete for the highest rankings even when it comes to highly competitive keywords.

Subscribe to our newsletter!

More from our blog

See all posts
No Comments

Recent Posts

Leave a Comment