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: