Expression tree of C # secret weapon

Source: Internet
Author: User

I. Getting started with expression trees

The lambda expression tree is complex and conceptually difficult to understand, in a word, the expression tree is a data structure! Here we use the following example to understand the expression tree, you can see a general:

Dynamic creation method for lambda expression tree

Static voidMain (string[] args) {            //i*j+w*xParameterExpression A = Expression.parameter (typeof(int),"I");//Create a parameter in an expression tree, as a node, this is the lowest nodeParameterExpression B = Expression.parameter (typeof(int),"J"); Binaryexpression R1= Expression.multiply (A, b);//here i*j, generate a node in the expression tree, one level higher than the above nodeparameterexpression C= Expression.parameter (typeof(int),"W"); ParameterExpression D= Expression.parameter (typeof(int),"x"); Binaryexpression R2=expression.multiply (c, D); Binaryexpression result= Expression.add (R1,R2);//operation of two intermediate nodes, generating endpointsExpression<Func<int,int,int,int,int>> lambda = expression.lambda<func<int,int,int,int,int>>(RESULT,A,B,C,D); Console.WriteLine (Lambda+"");//output ' (i,j,w,x) = ((i*j) + (w*x)) ', z corresponding parameter b,p corresponding parameter aFunc<int,int,int,int,int> f= lambda.compile ();//The lambda expression described by the expression tree is compiled into executable code and the delegate of the lambda expression is generated;Console.WriteLine (F (1,1,1,1) +"");//Output Results 2Console.readkey (); }

The above code consists of a lambda expression tree such as:

Ii. Some common expression tree usages

ConstantExpression: Represents an expression with a constant value

We build a console application

ConstantExpression _constexp = Expression.constant ("AAA",typeof(string));//a constant//Console.WriteLine ("AAA");methodcallexpression _methodcallexp=expression.call (typeof(Console). GetMethod ("WriteLine",Newtype[]{typeof(string)}), _constexp); Expression<Action> Consolelambdaexp = expression.lambda<action>(_METHODCALLEXP); Consolelambdaexp.compile () (); Console.ReadLine ();

Output a constant and look at the results

ParameterExpression : Represents a parameter Expression

ParameterExpression _parameexp = Expression.parameter (typeof(string),"Myparameter"); Methodcallexpression _methodcallexpp= Expression.call (typeof(Console). GetMethod ("WriteLine",NewType[] {typeof(string)}), _parameexp); Expression<Action<string>> _consstringexp = expression.lambda<action<string>>(_methodcallexpp, _parameexp); _consstringexp.compile () ("hello!!");

Output Result:

Methodcallexpression calling a static method

We build a static method that returns a string, passing in a value of type Object

 Public Static string Consstr (object  str) {    string"aa";    Console.WriteLine (_STR);     return _str;}
ParameterExpression _paraobj = Expression.parameter (typeof(Object),"Objpara"); Methodcallexpression _mystatemethod= Expression.call (typeof(program). GetMethod ("Consstr",NewType[] {typeof(Object)}), _paraobj); Expression<Func<Object,string>> _meylambdastate = expression.lambda<func<Object,string>>(_mystatemethod, _paraobj);stringS_TR = _meylambdastate.compile () ("ni Hao"); Console.WriteLine ("return Value:"+ s_tr);

Output Result:

 

Methodcallexpression Invoking instance methods

We write a non-static method

 Public string CONSSTR2 (object  str) {    string"aa";    Console.WriteLine (_STR);     return _str;}

Expression.call provides us with the overloads we want:

Program _PG =NewProgram (); ParameterExpression _paraobj2= Expression.parameter (typeof(Object),"Objpara"); Methodcallexpression _mystatemethod2= Expression.call (Expression.constant (_PG),typeof(program). GetMethod ("CONSSTR2"), _paraobj2); Expression<Func<Object,string>> _meylambdastate2 = expression.lambda<func<Object,string>>(_MYSTATEMETHOD2, _paraobj2);stringS_TR2 = _meylambdastate.compile () ("You shi ni"); Console.WriteLine ("return Value:"+ S_TR2);

Output Result:

Unaryexpression: unary operator expression

Use Unaryexpression to make a 5--expression:

ConstantExpression _consnum = expression.constant (5typeof(int=  Expression.decrement (_consnum); Expression<Func<int>> _unarylam = expression.lambda<func<int>>  (_unaryplus); Console.WriteLine (_unarylam.compile ());

Output Result:

Binaryexpression: Two-tuple operator expression

Binaryexpression We do an example of A+b

ParameterExpression _paraa = Expression.parameter (typeof(int),"a"); ParameterExpression _parab= Expression.parameter (typeof(int),"b"); Binaryexpression _binaadd=Expression.add (_paraa, _parab); Expression<Func<int,int,int>> _mybinaryaddlamb = expression.lambda<func<int,int,int>> (_binaadd,Newparameterexpression[] {_paraa, _parab}); Console.WriteLine ("An expression:"+_mybinaryaddlamb); Console.WriteLine (_mybinaryaddlamb.compile () (3,6));

Output Result:

Two expressions can also be put together: (a+b) * (--C)

ParameterExpression _paraa = Expression.parameter (typeof(int),"a"); ParameterExpression _parab= Expression.parameter (typeof(int),"b"); Binaryexpression _binaadd= Expression.add (_paraa, _parab);//a+bParameterExpression _parac = Expression.parameter (typeof(int),"C"); Unaryexpression _PARADECR= Expression.decrement (_parac);//(a+b) * (--c)Binaryexpression _binamultiply =expression.multiply (_binaadd, _PARADECR); Expression<Func<int,int,int,int>> _mybinarylamb = expression.lambda<func<int,int,int,int>> (_binamultiply,Newparameterexpression[] {_paraa, _parab, _parac}); Console.WriteLine ("An expression:"+_mybinarylamb); Console.WriteLine (_mybinarylamb.compile () (3,6,5));

Output Result:

Iii. Accessing properties using an expression tree

Expression trees can replace reflection, but not necessarily performance, to actually test it, also note that the compile call process involves dynamic code generation, so for performance reasons it's best to cache the resulting expression tree

The next step is to use expression tree to perform property assignments and values, which are implemented in the following two static methods: Creategetpropertyvaluefunc and Createsetpropertyvalueaction. Here is the definition of Creategetpropertyvaluefunc, which returns a func<object.object> delegate:

  Public Staticfunc<Object,Object>Creategetpropertyvaluefunc () {
varproperty =typeof(IFoo). GetProperty ("Bar"); vartarget = Expression.parameter (typeof(Object)); varCasttarget = Expression.convert (target,typeof(IFoo)); varGetPropertyValue =Expression.property (Casttarget, property); varCastpropertyvalue = Expression.convert (GetPropertyValue,typeof(Object)); returnexpression.lambda<func<Object,Object>>(Castpropertyvalue, target). Compile (); }

Here is the Createsetpropertyvalueaction method, which returns a action<object.object> delegate:

  Public Staticaction<Object,Object>createsetpropertyvalueaction () {varproperty =typeof(IFoo). GetProperty ("Bar"); vartarget = Expression.parameter (typeof(Object)); varPropertyValue = Expression.parameter (typeof(Object)); varCasttarget = Expression.convert (target,typeof(IFoo)); varCastpropertyvalue =Expression.convert (PropertyValue, property.        PropertyType); varsetPropertyValue =Expression.call (Casttarget, property.        GetSetMethod (), castpropertyvalue); returnexpression.lambda<action<Object,Object>>(setPropertyValue, Target, PropertyValue).   Compile (); }
Note: The expression tree water is very deep, here is only the introduction, still need to continue to study use ~

Expression tree of C # secret weapon

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.