zoukankan      html  css  js  c++  java
  • C#学习:表达式树

    通过表达式树拼装lambda表达式,从而实现把一个类型的字段和属性的值复制到另外一个类型中去。

    一、下面的方法实现两个类型间复制

        /// <summary>  
        /// 交换两个类型的属性(复制)  
        /// </summary>  
        /// <typeparam name="Tin"></typeparam>  
        /// <typeparam name="Tout"></typeparam>  
        public static class ExpressionCopy<Tin, Tout>  
        {  
            public static Tout Excharnge(Tin tin)  
            {  
                ParameterExpression experssionin = Expression.Parameter(typeof(Tin), "tModel");//创建实例  
                List<MemberBinding> memberList = new List<MemberBinding>();//绑定用的  
                foreach (var item in typeof(Tout).GetFields())
                {  
                    FieldInfo field = typeof(Tin).GetField(item.Name.GetPropertyRemark(typeof(Tout), 1));  
                    if (field != null)  
                    {  
                        MemberExpression member = Expression.Field(experssionin, field);  
                        MemberBinding binding = Expression.Bind(item, member);  
                        memberList.Add(binding);  
                    }  
                }  
        
                foreach (var item in typeof(Tout).GetProperties())
                {  
                    PropertyInfo pro = typeof(Tin).GetProperty(item.Name.GetPropertyRemark(typeof(Tout), 2));
                    if (pro != null)  
                    {  
                        MemberExpression proper = Expression.Property(experssionin, pro);  
                        MemberBinding binding = Expression.Bind(item, proper);  
                        memberList.Add(binding);  
                    }  
        
                }  
        
                MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(Tout)), memberList.ToArray());//初始化绑定新成员  
                Expression<Func<Tin, Tout>> lambda = Expression.Lambda<Func<Tin, Tout>>(init, new ParameterExpression[]  
                {   
                experssionin  
                });  
                return lambda.Compile().Invoke(tin);  
            }  
        }  

    二、声明特性为了防止当要复制的属性字段名称不一致

    /// <summary>  
        /// 特性  
        /// </summary>  
        public class GetRemarkAttribute : Attribute  
        {  
            public GetRemarkAttribute(string name)  
            {  
                this._remark = name;  
            }  
            private string _remark;  
            public string GetRemark()  
            {  
                return _remark;  
            }  
        }  

    三、通过反射为string类型添加一个扩展方法,来获取特性的值

     1 public static class GetRemark  
     2    {  
     3        /// <summary>  
     4        /// 通过反射获得特性  
     5        /// </summary>  
     6        /// <param name="values">字段属性名称</param>  
     7        /// <param name="type">类型</param>  
     8        /// <param name="parameter">参数1为字段2为属性</param>  
     9        /// <returns></returns>  
    10        public static string GetPropertyRemark(this string values, Type type, int parameter)  
    11        {  
    12            if (parameter == 1)  
    13            {  
    14                FieldInfo propperty = type.GetField(values);  
    15     
    16                if (propperty.IsDefined(typeof(GetRemarkAttribute)))  
    17                {  
    18                    GetRemarkAttribute remark = (GetRemarkAttribute)propperty.GetCustomAttribute(typeof(GetRemarkAttribute));  
    19                    return remark.GetRemark();  
    20                }  
    21     
    22            }  
    23            else  
    24            {  
    25                PropertyInfo propperty = type.GetProperty(values);  
    26     
    27                if (propperty.IsDefined(typeof(GetRemarkAttribute)))  
    28                {  
    29                    GetRemarkAttribute remark = (GetRemarkAttribute)propperty.GetCustomAttribute(typeof(GetRemarkAttribute));  
    30                    return remark.GetRemark();  
    31                }  
    32     
    33            }  
    34            return values;  
    35     
    36        }  
    37    }  

    四、下面就是实际操作调用

     1 public class OldPersoninfo  
     2     {  
     3         public int Id { get; set; }  
     4         public string Name { get; set; }  
     5         public string Type { get; set; }  
     6         public OldPersoninfo()  
     7         {  
     8             Id = 2;  
     9             Name = "测试";  
    10             Type = "非常类额";  
    11         }  
    12     }  
    13     public class NewPersoninfo  
    14     {  
    15         public int Id { get; set; }  
    16        // [GetRemark("Name")]  
    17         public string newName { get; set; }  
    18         //[GetRemark("Type")]  
    19         public string newType { get; set; }  
    20     }  
    21  
    22 
    23 private void test_Load(object sender, EventArgs e)  
    24        {  
    25            OldPersoninfo old = new OldPersoninfo();  
    26            NewPersoninfo newPersoninfo = ExpressionCopy<OldPersoninfo, NewPersoninfo>.Excharnge(old);  
    27            MessageBox.Show(newPersoninfo.newType);  
    28        }  
  • 相关阅读:
    交换函数swap的三种实现方法
    oracle如何修改某一列的数据类型
    安装 kibana 以及添加中文分词器
    linux 安装Elasticsearch
    docker添加tomcat容器成功无法访问首页
    docker run-it centos提示FATAL
    启动、重新启动容器后,进入交互模式
    获取阿里云docker加速器地址
    CentOS6 修改默认字符集为GBK
    linux中如何查看redis的版本
  • 原文地址:https://www.cnblogs.com/xiaojunwu/p/11811829.html
Copyright © 2011-2022 走看看