public MethodInfos()
        {
            GetUninitializedObject = GetFuncCall(() => FormatterServices.GetUninitializedObject(typeof(int)));
            GetTypeFromHandle      = GetFuncCall(() => Type.GetTypeFromHandle(typeof(Type).TypeHandle));
            CopyInner    = GetFuncCall(() => DeepCopier.Copy(default(object), default(CopyContext))).GetGenericMethodDefinition();
            TryGetCopy   = typeof(CopyContext).GetMethod("TryGetCopy");
            RecordObject = GetActionCall((CopyContext ctx) => ctx.RecordCopy(default(object), default(object)));

            CopyArrayRank1Shallow = GetFuncCall(() => ArrayCopier.CopyArrayRank1Shallow(default(object[]), default(CopyContext))).GetGenericMethodDefinition();
            CopyArrayRank1        = GetFuncCall(() => ArrayCopier.CopyArrayRank1(default(object[]), default(CopyContext))).GetGenericMethodDefinition();

            CopyArrayRank2Shallow = GetFuncCall(() => ArrayCopier.CopyArrayRank2Shallow(default(object[, ]), default(CopyContext))).GetGenericMethodDefinition();
            CopyArrayRank2        = GetFuncCall(() => ArrayCopier.CopyArrayRank2(default(object[, ]), default(CopyContext))).GetGenericMethodDefinition();

            MethodInfo GetActionCall <T>(Expression <Action <T> > expression)
            {
                return((expression.Body as MethodCallExpression)?.Method
                       ?? throw new ArgumentException("Expression type unsupported."));
            }

            MethodInfo GetFuncCall <T>(Expression <Func <T> > expression)
            {
                return((expression.Body as MethodCallExpression)?.Method
                       ?? throw new ArgumentException("Expression type unsupported."));
            }
        }
Exemple #2
0
        internal static T CopyArray <T>(T original, CopyContext context)
        {
            if (context.TryGetCopy(original, out var existingCopy))
            {
                return((T)existingCopy);
            }

            var originalArray = original as Array;

            if (originalArray == null)
            {
                throw new InvalidCastException($"Cannot cast non-array type {original?.GetType()} to Array.");
            }
            var elementType = original.GetType().GetElementType();

            var rank    = originalArray.Rank;
            var lengths = new int[rank];

            for (var i = 0; i < rank; i++)
            {
                lengths[i] = originalArray.GetLength(i);
            }

            var copyArray = Array.CreateInstance(elementType, lengths);

            context.RecordCopy(originalArray, copyArray);

            if (DeepCopier.CopyPolicy.IsShallowCopyable(elementType))
            {
                Array.Copy(originalArray, copyArray, originalArray.Length);
            }

            var index = new int[rank];
            var sizes = new int[rank];

            sizes[rank - 1] = 1;
            for (var k = rank - 2; k >= 0; k--)
            {
                sizes[k] = sizes[k + 1] * lengths[k + 1];
            }

            for (var i = 0; i < originalArray.Length; i++)
            {
                var k = i;
                for (var n = 0; n < rank; n++)
                {
                    var offset = k / sizes[n];
                    k        = k - offset * sizes[n];
                    index[n] = offset;
                }

                copyArray.SetValue(DeepCopier.Copy(originalArray.GetValue(index), context), index);
            }

            return((T)(object)copyArray);
        }
Exemple #3
0
        public MethodInfos()
        {
            this.GetUninitializedObject = GetFuncCall(() => FormatterServices.GetUninitializedObject(typeof(int)));
            this.GetTypeFromHandle      = GetFuncCall(() => Type.GetTypeFromHandle(typeof(Type).TypeHandle));
            this.CopyInner    = GetFuncCall(() => DeepCopier.Copy(default(object), default(CopyContext))).GetGenericMethodDefinition();
            this.RecordObject = GetActionCall((CopyContext ctx) => ctx.RecordCopy(default(object), default(object)));

            MethodInfo GetActionCall <T>(Expression <Action <T> > expression)
            {
                return((expression.Body as MethodCallExpression)?.Method
                       ?? throw new ArgumentException("Expression type unsupported."));
            }

            MethodInfo GetFuncCall <T>(Expression <Func <T> > expression)
            {
                return((expression.Body as MethodCallExpression)?.Method
                       ?? throw new ArgumentException("Expression type unsupported."));
            }
        }