static ReflectionInfos() { GetTypeFromHandle = GetFuncCall(() => Type.GetTypeFromHandle(typeof(Type).TypeHandle)); CompareInner = GetFuncCall(() => DeepComparer.Compare(default(object), default(object), default(CompareContext))).GetGenericMethodDefinition(); Skip = typeof(CompareContext).GetMethod(nameof(CompareContext.Skip)); CopyArrayRank1 = GetFuncCall(() => ArrayComparer.CopyArrayRank1(default(object[]), default(object[]), default(CompareContext))).GetGenericMethodDefinition(); CopyArrayRank2 = GetFuncCall(() => ArrayComparer.CopyArrayRank2(default(object[, ]), default(object[, ]), default(CompareContext))).GetGenericMethodDefinition(); // ReSharper disable once EqualExpressionComparison ReferenceEquals = GetFuncCall(() => ReferenceEquals(default(object), default(object))); ConvertDelegate = typeof(ReflectionInfos).GetMethod(nameof(_ConvertDelegate), BindingFlags.Static | BindingFlags.NonPublic); MethodInfo GetFuncCall <T>(Expression <Func <T> > expression) { return((expression.Body as MethodCallExpression)?.Method ?? throw new ArgumentException("Expression type unsupported.")); } }
internal static bool CopyArray <T>(T x, T y, CompareContext context) { if (ReferenceEquals(x, y)) { return(true); } var xArray = x as Array; if (xArray == null) { throw new InvalidCastException($"Cannot cast non-array type {x?.GetType()} to Array."); } var yArray = y as Array; if (yArray == null) { throw new InvalidCastException($"Cannot cast non-array type {y?.GetType()} to Array."); } var rank = xArray.Rank; if (rank != yArray.Rank) { return(false); } var lengths = new int[rank]; for (var i = 0; i < rank; i++) { var length = xArray.GetLength(i); if (length != yArray.GetLength(i)) { return(false); } lengths[i] = 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 < xArray.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; } var xItem = xArray.GetValue(index); var yItem = yArray.GetValue(index); if (context.Skip(xItem, yItem) == false) { var result = DeepComparer.Compare(xItem, yItem, context); if (result == false) { return(false); } } } return(true); }