public virtual Action <TSource, TTarget, CircularRefChecker> GenerateDefaultCopyToDelegate() { Type sType = typeof(TSource); Type tType = typeof(TTarget); ParameterExpression sourcePar = Expression.Parameter(sType, "source"); ParameterExpression targetPar = Expression.Parameter(tType, "target"); ParameterExpression targetVar = Expression.Variable(tType); ParameterExpression crCheckerPar = Expression.Parameter(typeof(CircularRefChecker), "checker"); var g = new PropertyAssignGenerator(sourcePar, targetVar, crCheckerPar, _provider); var exp = g.GenerateExpression(); List <Expression> expList = new List <Expression>() { }; if (exp != null) { if (PropertyAssignGenerator.IsDictionaryType(tType)) { var argTypes = tType.GetGenericArguments(); MethodInfo mi = this.GetType().GetMethod("CopyToDictionay"); mi = mi.MakeGenericMethod(argTypes[0], argTypes[1]); expList.Add(exp); expList.Add(Expression.Call(Expression.Constant(this), mi, targetVar, targetPar)); } else if (PropertyAssignGenerator.IsListType(tType)) { var argTypes = tType.GetGenericArguments(); MethodInfo mi = this.GetType().GetMethod("CopyToList"); mi = mi.MakeGenericMethod(argTypes[0]); expList.Add(exp); expList.Add(Expression.Call(Expression.Constant(this), mi, targetVar, targetPar)); } else { // 单值不存在CopyTo return((s, t, checker) => { }); } } else { // 类转换 expList.AddRange(GeneratePropertyAssignExpression(sourcePar, targetPar, crCheckerPar, true)); } return(Expression.Lambda <Action <TSource, TTarget, CircularRefChecker> >( Expression.Block( new ParameterExpression[] { targetVar }, Expression.IfThen( Expression.NotEqual(Expression.Constant(targetPar), Expression.Constant(null)), Expression.Block(expList)) ), sourcePar, targetPar, crCheckerPar).Compile()); }
public virtual Expression ConvertProperty(ParameterExpression source, ParameterExpression checkerPar, PropertyInfo spi, Expression target, PropertyInfo tpi, bool isCopy, MemberInitExpression excludeProperties) { ParameterExpression se = ParameterExpression.Variable(spi.PropertyType); ParameterExpression te = ParameterExpression.Variable(tpi.PropertyType); List <Expression> expList = new List <Expression>(); PropertyAssignGenerator g = new PropertyAssignGenerator(se, te, checkerPar, _provider); Expression e = g.GenerateExpression(true); if (e != null) { expList.Add(Expression.Assign(se, Expression.MakeMemberAccess(source, spi))); if (isCopy) { //拷贝 Type tType = tpi.PropertyType; if ((tType.IsClass && tType != typeof(string)) || PropertyAssignGenerator.IsDictionaryType(tType) || PropertyAssignGenerator.IsListType(tType)) { List <Expression> exp = new List <Expression>(); if (tType.IsClass) { exp.Add(Expression.Assign(te, Expression.MakeMemberAccess(target, tpi))); if (excludeProperties != null) { exp.Add(GenerateExcludeAction(spi.PropertyType, tType, se, te, excludeProperties)); } else { exp.Add(g.GenerateCopyToExpression()); } } else if (PropertyAssignGenerator.IsDictionaryType(tType)) { var argTypes = tType.GetGenericArguments(); MethodInfo mi = this.GetType().GetMethod("CopyToDictionay"); mi = mi.MakeGenericMethod(argTypes[0], argTypes[1]); exp.Add(e); exp.Add(Expression.Call(Expression.Constant(this), mi, te, Expression.MakeMemberAccess(target, tpi))); } else if (PropertyAssignGenerator.IsListType(tType)) { var argTypes = tType.GetGenericArguments(); MethodInfo mi = this.GetType().GetMethod("CopyToList"); mi = mi.MakeGenericMethod(argTypes[0]); exp.Add(e); exp.Add(Expression.Call(Expression.Constant(this), mi, te, Expression.MakeMemberAccess(target, tpi))); } // 如果te等于null,new expList.Add(Expression.IfThenElse( Expression.Equal(Expression.MakeMemberAccess(target, tpi), Expression.Constant(null)), Expression.Block( e, Expression.Assign( Expression.MakeMemberAccess(target, tpi), te) ), Expression.IfThenElse( Expression.Equal(se, Expression.Constant(null)), Expression.Assign(Expression.MakeMemberAccess(target, tpi), Expression.Constant(null, tpi.PropertyType)), Expression.Block(exp) ) )); return(Expression.Block( new ParameterExpression[] { se, te }, expList)); } } expList.Add(e); expList.Add(Expression.Assign( Expression.MakeMemberAccess(target, tpi), te)); return(Expression.Block( new ParameterExpression[] { se, te }, expList)); } return(null); }