private Expression CreateDeepCopyRectangulerArrayExpression( Type type, Type elementType, Expression source, Expression destination, Expression cache) { int rank = type.GetArrayRank(); var indexes = Enumerable.Range(0, rank) .Select(x => Expression.Parameter(typeof(int), $"i{x}")) .ToArray(); var lengths = Enumerable.Range(0, rank) .Select(x => ExpressionUtils.GetArrayLength(source, x)) .ToArray(); var arrayAssign = Expression.Assign( destination, Expression.NewArrayBounds(elementType, lengths)); var elementAssign = elementType.IsArray ? Build( TypeUtils.IsValueType(elementType.GetElementType()) ? CopyPolicy.ShallowCopy : CopyPolicy.DeepCopy, elementType, Expression.ArrayIndex(source, indexes), Expression.ArrayAccess(destination, indexes), cache) : ClassCloner.Instance.Build( elementType, Expression.ArrayIndex(source, indexes), Expression.ArrayAccess(destination, indexes), cache); Expression Loop(int rankIndex) { var endLoop = Expression.Label($"EndLoop{rankIndex}"); return(Expression.Block( Expression.Assign(indexes[rankIndex], ExpressionUtils.Zero), Expression.Loop( Expression.Block( Expression.IfThen( Expression.GreaterThanOrEqual(indexes[rankIndex], lengths[rankIndex]), Expression.Break(endLoop)), rankIndex < rank - 1 ? Loop(rankIndex + 1) : elementAssign, Expression.PreIncrementAssign(indexes[rankIndex])), endLoop))); } return(Expression.Block( indexes, indexes.Select(i => Expression.Assign(i, ExpressionUtils.Zero)) .Concat(new[] { arrayAssign, Loop(0) }))); }