示例#1
0
        private static Expression GenerateJaggedArray(List <ParameterExpression> variables,
                                                      ParameterExpression source,
                                                      ParameterExpression clone,
                                                      Type sourceType,
                                                      ParameterExpression refTrackerParam)
        {
            var elementType = sourceType.GetElementType();

            var item       = Expression.Parameter(elementType, "item");
            var clonedItem = Expression.Parameter(elementType, "item");
            var typeExpr   = Expression.Parameter(typeof(Type), "typeExpr");
            var i          = Expression.Parameter(typeof(int), "i");
            var length     = Expression.Parameter(typeof(int), "length");

            variables.Add(typeExpr);
            variables.Add(clonedItem);
            variables.Add(item);
            variables.Add(length);
            variables.Add(i);

            var notTrackedExpressions = new List <Expression>();

            notTrackedExpressions.Add(Expression.Assign(length, Expression.Property(source, "Length")));
            notTrackedExpressions.Add(Expression.Assign(i, Expression.Constant(0)));
            notTrackedExpressions.Add(Expression.Assign(clone, Expression.Convert(Expression.New(sourceType.GetConstructor(new[] { typeof(int) }), length), sourceType)));
            notTrackedExpressions.Add(Expression.Call(refTrackerParam, ObjectClonerReferenceTrackerMih.Track(), source, clone));

            Debug.Assert(!elementType.IsPrimitive && !elementType.IsValueType && elementType != typeof(string), "Element type cannot be a primitive type");

            var loopExpressions = new List <Expression>();

            loopExpressions.Add(Expression.Assign(item, Expression.Convert(Expression.Call(source, ArrayMih.GetValue(), i), elementType)));
            loopExpressions.Add(ClassCloner.GetCloneClassTypeExpression(refTrackerParam, item, clonedItem, elementType));
            loopExpressions.Add(Expression.Call(clone, ArrayMih.SetValue(), Expression.Convert(clonedItem, typeof(object)), i));
            loopExpressions.Add(Expression.Assign(i, Expression.Add(i, Expression.Constant(1))));

            var cond     = Expression.LessThan(i, length);
            var loopBody = Expression.Block(loopExpressions);

            var breakLabel = Expression.Label("breakLabel");
            var loop       = Expression.Loop(Expression.IfThenElse(cond,
                                                                   loopBody,
                                                                   Expression.Break(breakLabel)),
                                             breakLabel);

            notTrackedExpressions.Add(loop);

            return(ObjectCloner.GenerateNullTrackedOrUntrackedExpression(source,
                                                                         clone,
                                                                         sourceType,
                                                                         refTrackerParam,
                                                                         Expression.Block(notTrackedExpressions)));
        }
示例#2
0
        private static Func <EnumerableLoopBodyCargo, Expression> GetLoopBodyCargo(ParameterExpression siClone, ParameterExpression clonedItem, ParameterExpression refTrackerParam)
        {
            Func <EnumerableLoopBodyCargo, Expression> loopBody = cargo =>
            {
                var keyExpression   = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetProperty("Current")), cargo.KvpType.GetProperty("Name"));
                var valueExpression = Expression.Property(Expression.Property(cargo.Enumerator, cargo.EnumeratorType.GetProperty("Current")), cargo.KvpType.GetProperty("Value"));
                var cloneValueExpr  = Expression.Block(ClassCloner.GetCloneClassTypeExpression(refTrackerParam, valueExpression, clonedItem, typeof(object)),
                                                       Expression.Call(siClone, SerializationInfoMih.AddValue(), keyExpression, clonedItem));

                return(Expression.IfThenElse(Expression.Equal(valueExpression, Expression.Constant(null)),
                                             Expression.Call(siClone, SerializationInfoMih.AddValue(), keyExpression, Expression.Constant((object)null, typeof(object))),
                                             cloneValueExpr));
            };

            return(loopBody);
        }
示例#3
0
        private static IEnumerable <Expression> GenerateCopyDimensionalArray(ParameterExpression sourceArray,
                                                                             ParameterExpression cloneArray,
                                                                             Type sourceType,
                                                                             List <ParameterExpression> variables,
                                                                             ParameterExpression lengths,
                                                                             int rank,
                                                                             ParameterExpression refTrackerParam)
        {
            var elementType = sourceType.GetElementType();

            var item       = Expression.Parameter(elementType, "item");
            var clonedItem = Expression.Parameter(elementType, "clonedItem");
            var typeExpr   = Expression.Parameter(typeof(Type), "typeExpr");
            var indices    = Expression.Parameter(typeof(int[]), "indices");

            variables.Add(typeExpr);
            variables.Add(item);
            variables.Add(indices);
            variables.Add(clonedItem);

            var expressions = new List <Expression>();

            expressions.Add(Expression.Assign(indices, Expression.Call(CreateArrayMethodInfo.GetCreateArrayMethodInfo(typeof(int)), Expression.Constant(rank))));

            Debug.Assert(!(elementType.IsPrimitive || elementType.IsValueType || elementType == typeof(string)), "This method is not made to handle primitive types");

            Expression innerExpression = Expression.Block(ClassCloner.GetCloneClassTypeExpression(refTrackerParam, item, clonedItem, elementType),
                                                          Expression.Call(cloneArray, ArrayMih.SetValueRank(), Expression.Convert(clonedItem, typeof(object)), indices));

            Func <int, Expression, Expression> makeArrayLoop = (loopRank,
                                                                innerExpr) =>
            {
                var loopRankIndex = Expression.Parameter(typeof(int), "loopRankIndex" + loopRank);
                variables.Add(loopRankIndex);

                var loopExpressions = new List <Expression>();

                loopExpressions.Add(Expression.Assign(Expression.ArrayAccess(indices, Expression.Constant(loopRank)), loopRankIndex));
                loopExpressions.Add(Expression.Assign(item, Expression.Convert(Expression.Call(sourceArray, ArrayMih.GetValueRank(), indices), elementType)));
                loopExpressions.Add(innerExpr);
                loopExpressions.Add(Expression.Assign(loopRankIndex, Expression.Add(loopRankIndex, Expression.Constant(1))));

                var cond     = Expression.LessThan(loopRankIndex, Expression.ArrayIndex(lengths, Expression.Constant(loopRank)));
                var loopBody = Expression.Block(loopExpressions);

                var breakLabel = Expression.Label("breakLabel" + loopRank);
                var loop       = Expression.Loop(Expression.IfThenElse(cond,
                                                                       loopBody,
                                                                       Expression.Break(breakLabel)),
                                                 breakLabel);
                return(Expression.Block(Expression.Assign(loopRankIndex, Expression.Constant(0)),
                                        loop));
            };

            for (int r = rank - 1; r >= 0; r--)
            {
                innerExpression = makeArrayLoop(r, innerExpression);
            }

            expressions.Add(innerExpression);

            return(expressions);
        }