"Traversal" of an object's properties using the expression tree (Expression)

Source: Internet
Author: User
Tags reflection

Article reading order suggested: This series has a progressive order, you can read the following article: first, the use of delegate to an unknown type of object "traversal" http://blog.csdn.net/kmguo/article/details/ 173,921,852. The expression tree (Expression) is used to "traverse" the properties of an object http://blog.csdn.net/kmguo/article/details/19975331
Using the expression tree (Expression block) to "traverse" the properties of an object
http://blog.csdn.net/kmguo/article/details/20376187




In addition to the way direct access to a class is made, there are currently three ways to read the properties or fields of an object of an unknown type. The first, the most common reflection, is simple to implement, but poor performance if you want to access a large number of objects of the same type each time. The second is the use of delegate, see: "The adoption of delegate to an object traversal, http://blog.csdn.net/kmguo/article/details/17392185" This approach also has shortcomings, Is that you cannot read a property or field of a non-basic type and a (String) type. Example:

public class Student
    {public
        int Id {get; set;}
        public string Name {get; set;}
        Public Location Location {get; set;}
    } 


    public class Location 
    {public 
        int Row {get; set;} 
        public int Col {get; set;} 
    }
In a delegate way, you can only get the ID and name value of the instance object of student, which is related to the special of the string class, because the ToString () method that calls it can directly get the string we want. Instead of getting the row and Col values in location (because the ToString method of the location instance does not return the row and Col property values we want).
However, you can use the expression tree to get the expression tree first, and finally compile the expression tree into delegate to access it. Suppose a student object is: Student, in general, we have the following access methods for all of its public properties: property name                 & nbsp           Normal access mode                       &NB Sp        delegate access mode (func<student, object>) Id                                       student. Id                                         S=>s.id Name                         & nbsp      student. Name                                 &NBSP ; S=>s.name location.row                   student. Location.row                      s=>s.location.row Location.col                      student. Location.col                        s=>s.location.col
Now, we can use expression tree to "simulate" the way delegate access, and eventually "compiled" into delegate, that is, func<tin,tout>. To further illustrate the function of using expression tree, it is assumed that we are going to get the value of all the public properties of an object of an unknown type, and if the property is not a base type or string, the value of its internal public property is further obtained. Take the student object above as an example.
Using System;
Using System.Linq.Expressions;
Using System.Reflection; Namespace ConsoleApplication1 {class Program {static void Main (string[] args) {Obje CT student = new Student {Id = 1, Name = "Zhang San", Locatio
            n = new Location {Row = ten, Col = 20}
           };
        Visitproperties<student> (Student); ///<summary>///Recursive access to properties of objects of unknown type///</summary>///<typeparam name= " T "></typeparam>///<param name=" obj "></param> static void Visitproperties<t> (O Bject obj) {var type = obj.
            GetType ();
            var paraexpression = Expression.parameter (typeof (T), "Object"); foreach (var prop in type.) GetProperties ()) {var proptype = Prop.
 PropertyType;               The expression tree that determines whether the base type or string//access method is: obj =>obj. Property if (proptype.isprimitive | | proptype = = typeof (String)) {Vi
                Sitproperty<t> (obj, prop, paraexpression, paraexpression); } else {//the expression tree for the access method is: Obj=>obj.otherobj.pro

                    Perty. Console.WriteLine ("Not primitive property:" + Prop.)
                    Name); var othertype = Prop.
                    PropertyType;
                    Memberexpression memberexpression = Expression.property (paraexpression, prop);
                        Access all public properties in the Obj.otherobj foreach (Var otherprop in othertype.getproperties ()) {
                    Visitproperty<t> (obj, Otherprop, memberexpression, paraexpression);
         } Console.WriteLine ("--------------------------------");   }///<summary>///execution expression tree is: Obj=>obj. Calculation of property or Obj=>obj.otherobj.property///</summary>///<param name= "Instanceexpression" &G
        t; representation of the expression tree of the Obj object of the final Access property </param>///<param name= "parameterexpression" > type T the expression of the tree of parameter expressions </param> static void Visitproperty<t> (Object obj, PropertyInfo prop, Expression instanceexpression, ParameterExpression PA Rameterexpression) {Console.WriteLine ("Property name:" + Prop.)

            Name);
            Memberexpression memexpression = Expression.property (instanceexpression, prop); Implement type conversions, such as converting the int type of ID to type object to facilitate the following versatility Expression objectexpression = Expression.convert (Memexpression, typeof (
            object)); Expression<func<t, object>> lambdaexpression = expression.lambda<func<t, object>> (
            Objectexpression, parameterexpression); Print expression tree Console.WriteLine ("Expression trees:"+ lambdaexpression);
            Func<t, object> Func = Lambdaexpression.compile (); Console.WriteLine ("Value:" + func ((T) obj));
 Print out the resulting property value}}

Execution results:


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.