using System; using System.Collections.Generic; using System.Linq.Expressions; namespace Masuit.Tools.Mapping { /// /// 表达式树复制对象 /// /// public static class Copier { private static readonly ParameterExpression ParameterExpression = Expression.Parameter(typeof(T), "p"); private static Func _func; private static readonly Dictionary DictRule = new Dictionary(); /// /// 深拷贝 /// /// /// public static T Copy(T source) { if (_func != null) { return _func.Invoke(source); } var memberBindings = new List(); foreach (var item in typeof(T).GetProperties()) { if (DictRule.ContainsKey(item.Name)) { MemberBinding memberBinding = Expression.Bind(item, DictRule[item.Name]); memberBindings.Add(memberBinding); } else { var tInProperty = typeof(T).GetProperty(item.Name); var tInField = typeof(T).GetField(item.Name); if (tInProperty != null || tInField != null) { MemberExpression property = Expression.PropertyOrField(ParameterExpression, item.Name); MemberBinding memberBinding = Expression.Bind(item, property); memberBindings.Add(memberBinding); } } } foreach (var item in typeof(T).GetFields()) { if (DictRule.ContainsKey(item.Name)) { MemberBinding memberBinding = Expression.Bind(item, DictRule[item.Name]); memberBindings.Add(memberBinding); } else { var tInProperty = typeof(T).GetProperty(item.Name); var tInField = typeof(T).GetField(item.Name); if (tInProperty != null || tInField != null) { MemberExpression property = Expression.PropertyOrField(ParameterExpression, item.Name); MemberBinding memberBinding = Expression.Bind(item, property); memberBindings.Add(memberBinding); } } } var memberInitExpression = Expression.MemberInit(Expression.New(typeof(T)), memberBindings.ToArray()); var lambda = Expression.Lambda>(memberInitExpression, ParameterExpression); _func = lambda.Compile(); return _func.Invoke(source); } } }