采用表达式树(Expression Tree)对一个对象的属性进行“遍历”

实体类:

    public class Student  
        {  
            public int Id { get; set; }  
            public string Name { get; set; }  
            public string[] MultipleCareers { get; set; }
            public Location Location { get; set; }  
        }   


        public class Location   
        {   
            public int Row { get; set; }   
            public int Col { get; set; }   
        }  

Program.cs代码:

 class Program
    {
        private static void Main(string[] args)
        {
            object student = new Student
            {
                Id = 1,
                Name = "zhang san",
                MultipleCareers =new string[]{"教师","程序员","作家","画家"},
                Location = new Location
                {
                    Row = 10,
                    Col = 20
                }
            };
            VisitProperties<Student>(student);
        }

        /// <summary>
        ///     对未知类型的对象的属性进行递归访问
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        private static void VisitProperties<T>(object obj)
        {
            Type type = obj.GetType();
            ParameterExpression paraExpression = Expression.Parameter(typeof (T), "object");
            foreach (PropertyInfo prop in type.GetProperties())
            {
                Type propType = prop.PropertyType;
                //判断是否为基本类型或String  
                //访问方式的表达式树为:obj =>obj.Property  
                if (propType.IsPrimitive || propType == typeof (String))
                {
                    VisitProperty<T>(obj, prop, paraExpression, paraExpression);
                }

                else
                {
                    //对于访问方式的表达式树为: obj=>obj.otherObj.Property。  
                    Console.WriteLine("not primitive property: " + prop.Name);
                    Type otherType = prop.PropertyType;
                    MemberExpression memberExpression = Expression.Property(paraExpression, prop);
                    //访问obj.otherObj里的所有公有属性  
                    foreach (PropertyInfo otherProp in otherType.GetProperties())
                    {
                        VisitProperty<T>(obj, otherProp, memberExpression, paraExpression);
                    }
                }
                Console.WriteLine("--------------------------------");
            }
        }

        /// <summary>
        ///     执行表达式树为: obj=>obj.Property 或 obj=>obj.otherObj.Property的计算
        /// </summary>
        /// <param name="instanceExpression">最终访问属性的obj对象的表达式树的表示</param>
        /// <param name="parameterExpression">类型T的参数表达式树的表示</param>
        private static void VisitProperty<T>(Object obj, PropertyInfo prop, Expression instanceExpression, ParameterExpression parameterExpression)
        {
            Console.WriteLine("property name: " + prop.Name);

            MemberExpression memExpression = Expression.Property(instanceExpression, prop);
            //实现类型转换,如将Id的int类型转为object类型,便于下面的通用性  
            Expression objectExpression = Expression.Convert(memExpression, typeof (object));
            Expression<Func<T, object>> lambdaExpression = Expression.Lambda<Func<T, object>>(objectExpression,
                parameterExpression);
            //打印表达式树  
            Console.WriteLine("expression tree: " + lambdaExpression);
            Func<T, object> func = lambdaExpression.Compile();
            Console.WriteLine("value: " + func((T) obj)); //打印出得到的属性值  
        }
    }

运行结果如图:

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值