1 //缓存表达式树 2 private static Dictionary<string, object> objCache = new Dictionary<string, object>(); 3 4 /// <summary> 5 /// 使用表达式树为两个对象的相同属性赋值 6 /// </summary> 7 /// <typeparam name="TIn">源对象</typeparam> 8 /// <typeparam name="TOut">目标对象</typeparam> 9 /// <param name="tIn">源实例</param> 10 /// <returns>目标实例</returns> 11 private static TOut ObjCopyByExpressionTree<TIn, TOut>(TIn tIn) 12 { 13 string key = string.Format("Key_{0}_To_{1}", typeof(TIn).FullName, typeof(TOut).FullName); 14 if (!objCache.ContainsKey(key)) 15 { 16 //表示一个命名的参数表达式 17 //创建一个 System.Linq.Expressions.ParameterExpression 节点,该节点可用于标识表达式树中的参数或变量 18 // type: 19 // 参数或变量的类型。 20 // 21 // name: 22 // 仅用于调试或打印目的的参数或变量的名称 23 ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "parameter"); 24 25 //提供表示绑定的类派生自的基类,这些绑定用于对新创建对象的成员进行初始化 26 List<MemberBinding> memberBindingList = new List<MemberBinding>(); 27 28 foreach (var item in typeof(TOut).GetProperties()) 29 { 30 //表示访问字段或属性 31 // expression: 32 // 要将 System.Linq.Expressions.Expression 属性设置为与其相等的 System.Linq.Expressions.MemberExpression.Expression。 33 // 对于静态属性,这可以为 null。 34 // 35 // property: 36 // 要将 System.Reflection.PropertyInfo 属性设置为与其相等的 System.Linq.Expressions.MemberExpression.Member。 37 MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name)); 38 39 //提供表示绑定的类派生自的基类,这些绑定用于对新创建对象的成员进行初始化。 40 MemberBinding memberBinding = Expression.Bind(item, property); 41 42 memberBindingList.Add(memberBinding); 43 }; 44 45 //表示调用构造函数并初始化新对象的一个或多个成员。 46 MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray()); 47 48 //将强类型化的 Lambda 表达式表示为表达式树形式的数据结构 49 Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[] { parameterExpression }); 50 51 //封装一个方法,该方法具有一个参数,且返回由 TResult 参数指定的类型的值 52 //编译表达式树由描述为可执行代码的 lambda 表达式,并生成一个委托,表示 lambda 表达式 53 Func<TIn, TOut> func = lambda.Compile(); 54 55 objCache[key] = func; 56 } 57 return ((Func<TIn, TOut>)objCache[key])(tIn); 58 }