Example #1
0
        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());
        }
Example #2
0
        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);
        }