其他分享
首页 > 其他分享> > .net 利用反射和表达式树 实现两个类之间的赋值

.net 利用反射和表达式树 实现两个类之间的赋值

作者:互联网


    /// <summary>
    /// 实体类
    /// </summary>
    public class People
    {
        public int Age { get; set; }
        public string Name { get; set; }

        public int Id;
    }

    /// <summary>
    /// 实体类
    /// </summary>
    public class PeopleCopy
    {
        public int Age { get; set; }
        public string Name { get; set; }

        public int Id;
    }

在生活中我们会遇到类似把People字段的值赋值给PeoPleCopy,我们可以直接反射来做,但是反射效率不高,所以我们这里用反射+拼接表达式树的方式来实现

 private static Dictionary<string, object> _Dic = new Dictionary<string, object>();
        private static TOut TransExp<TIn, TOut>(TIn tIn)
        {
            string key = string.Format("funckey_{0}_{1}", typeof(TIn).FullName, typeof(TOut).FullName);
            if (!_Dic.ContainsKey(key))
            {
                ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
                List<MemberBinding> memberBindingList = new List<MemberBinding>();
                foreach (var item in typeof(TOut).GetProperties())
                {
                    MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                foreach (var item in typeof(TOut).GetFields())
                {
                    MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
                Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[]
                {
                parameterExpression
                });
                Func<TIn, TOut> func = lambda.Compile();//拼装是一次性的

                _Dic[key] = func;
            }
            return ((Func<TIn, TOut>)_Dic[key]).Invoke(tIn);
        }

定义静态变量的意义在于我们只用拼接一次数据,以后再次调用赋值的时候直接读取以前拼接好的表达式

调用   PeopleCopy peopleCopy1 = Trans<People, PeopleCopy>(people); 就可以了

 

标签:item,TIn,TOut,typeof,net,Expression,public,表达式,赋值
来源: https://blog.csdn.net/wu1020300665/article/details/88618915