using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace Ant.Core.Utils { /// <summary> /// 高效实体转换(浅拷贝)(反射+表达式目录树+静态缓存 方式) /// </summary> /// <typeparam name="TIn"></typeparam> /// <typeparam name="TOut"></typeparam> public static class SafeClone<TIn, TOut> { private static readonly Func<TIn, TOut> cache = GetFunc(); private static Func<TIn, TOut> GetFunc() { ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p"); List<MemberBinding> memberBindingList = new List<MemberBinding>(); foreach (var item in typeof(TOut).GetProperties()) { if (!item.CanWrite) continue; var tInProperty = typeof(TIn).GetProperties().FirstOrDefault(x => x.Name == item.Name); if (tInProperty != null && tInProperty.PropertyType == item.PropertyType) { MemberExpression property = Expression.Property(parameterExpression, tInProperty); 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 }); return lambda.Compile(); } public static TOut Trans(TIn tIn) { return cache(tIn); } } }