internal static object CloneClassInternal(object obj, DeepCloneState state) { if (obj == null) { return(null); } var cloner = (Func <object, DeepCloneState, object>)DeepClonerCache.GetOrAddClass(obj.GetType(), t => GenerateCloner(t, true)); // safe ojbect if (cloner == null) { return(obj); } // loop var knownRef = state.GetKnownRef(obj); if (knownRef != null) { return(knownRef); } return(cloner(obj, state)); }
internal static T[] Clone1DimArraySafeInternal <T>(T[] obj, DeepCloneState state) { T[] array = new T[obj.Length]; state.AddKnownRef(obj, array); Array.Copy(obj, array, obj.Length); return(array); }
internal static Array CloneAbstractArrayInternal(Array obj, DeepCloneState state) { if (obj != null) { int rank = obj.Rank; int[] array = Enumerable.Range(0, rank).Select(obj.GetLowerBound).ToArray(); int[] array2 = Enumerable.Range(0, rank).Select(obj.GetLength).ToArray(); int[] array3 = Enumerable.Range(0, rank).Select(obj.GetLowerBound).ToArray(); Array array4 = Array.CreateInstance(obj.GetType().GetElementType(), array2, array); state.AddKnownRef(obj, array4); while (true) { array4.SetValue(CloneClassInternal(obj.GetValue(array3), state), array3); int num = rank - 1; while (true) { array3[num]++; if (array3[num] < array[num] + array2[num]) { break; } array3[num] = array[num]; num--; if (num < 0) { return(array4); } } } } return(null); }
internal static T[] Clone1DimArraySafeInternal <T>(T[] objFrom, T[] objTo, DeepCloneState state) { int length = Math.Min(objFrom.Length, objTo.Length); state.AddKnownRef(objFrom, objTo); Array.Copy(objFrom, objTo, length); return(objTo); }
internal static T[,] Clone2DimArrayInternal <T>(T[,] objFrom, T[,] objTo, DeepCloneState state, bool isDeep) { if (objFrom == null || objTo == null) { return(null); } int num = Math.Min(objFrom.GetLength(0), objTo.GetLength(0)); int num2 = Math.Min(objFrom.GetLength(1), objTo.GetLength(1)); state.AddKnownRef(objFrom, objTo); if ((!isDeep || DeepClonerSafeTypes.CanNotCopyType(typeof(T), null)) && objFrom.GetLength(0) == objTo.GetLength(0) && objFrom.GetLength(1) == objTo.GetLength(1)) { Array.Copy(objFrom, objTo, objFrom.Length); return(objTo); } if (!isDeep) { for (int i = 0; i < num; i++) { for (int j = 0; j < num2; j++) { int num3 = i; int num4 = j; T val = objFrom[i, j]; objTo[num3, num4] = val; } } return(objTo); } if (typeof(T).IsValueType()) { Func <T, DeepCloneState, T> clonerForValueType = DeepClonerGenerator.GetClonerForValueType <T>(); for (int k = 0; k < num; k++) { for (int l = 0; l < num2; l++) { int num5 = k; int num6 = l; T val2 = clonerForValueType(objFrom[k, l], state); objTo[num5, num6] = val2; } } } else { for (int m = 0; m < num; m++) { for (int n = 0; n < num2; n++) { int num7 = m; int num8 = n; T obj = (T)DeepClonerGenerator.CloneClassInternal(objFrom[m, n], state); objTo[num7, num8] = obj; } } } return(objTo); }
// when we can't use code generation, we can use these methods internal static T[] Clone1DimArraySafeInternal <T>(T[] obj, DeepCloneState state) { var l = obj.Length; var outArray = new T[l]; state.AddKnownRef(obj, outArray); Array.Copy(obj, outArray, obj.Length); return(outArray); }
private static T CloneStructInternal <T>(T obj, DeepCloneState state) { Func <T, DeepCloneState, T> clonerForValueType = GetClonerForValueType <T>(); if (clonerForValueType == null) { return(obj); } return(clonerForValueType(obj, state)); }
internal static T[,] Clone2DimArrayInternal <T>(T[,] objFrom, T[,] objTo, DeepCloneState state, bool isDeep) { // not null from called method, but will check it anyway if (objFrom == null || objTo == null) { return(null); } var l1 = Math.Min(objFrom.GetLength(0), objTo.GetLength(0)); var l2 = Math.Min(objFrom.GetLength(1), objTo.GetLength(1)); state.AddKnownRef(objFrom, objTo); if ((!isDeep || DeepClonerSafeTypes.CanReturnSameObject(typeof(T))) && objFrom.GetLength(0) == objTo.GetLength(0) && objFrom.GetLength(1) == objTo.GetLength(1)) { Array.Copy(objFrom, objTo, objFrom.Length); return(objTo); } if (!isDeep) { for (var i = 0; i < l1; i++) { for (var k = 0; k < l2; k++) { objTo[i, k] = objFrom[i, k]; } } return(objTo); } if (typeof(T).IsValueType()) { var cloner = DeepClonerGenerator.GetClonerForValueType <T>(); for (var i = 0; i < l1; i++) { for (var k = 0; k < l2; k++) { objTo[i, k] = cloner(objFrom[i, k], state); } } } else { for (var i = 0; i < l1; i++) { for (var k = 0; k < l2; k++) { objTo[i, k] = (T)DeepClonerGenerator.CloneClassInternal(objFrom[i, k], state); } } } return(objTo); }
// rare cases, very slow cloning. currently it's ok internal static Array CloneAbstractArrayInternal(Array objFrom, Array objTo, DeepCloneState state, bool isDeep) { // not null from called method, but will check it anyway if (objFrom == null || objTo == null) { return(null); } var rank = objFrom.Rank; if (objTo.Rank != rank) { throw new InvalidOperationException("Invalid rank of target array"); } var lowerBoundsFrom = Enumerable.Range(0, rank).Select(objFrom.GetLowerBound).ToArray(); var lowerBoundsTo = Enumerable.Range(0, rank).Select(objTo.GetLowerBound).ToArray(); var lengths = Enumerable.Range(0, rank).Select(x => Math.Min(objFrom.GetLength(x), objTo.GetLength(x))).ToArray(); var idxesFrom = Enumerable.Range(0, rank).Select(objFrom.GetLowerBound).ToArray(); var idxesTo = Enumerable.Range(0, rank).Select(objTo.GetLowerBound).ToArray(); state.AddKnownRef(objFrom, objTo); while (true) { if (isDeep) { objTo.SetValue(DeepClonerGenerator.CloneClassInternal(objFrom.GetValue(idxesFrom), state), idxesTo); } else { objTo.SetValue(objFrom.GetValue(idxesFrom), idxesTo); } var ofs = rank - 1; while (true) { idxesFrom[ofs]++; idxesTo[ofs]++; if (idxesFrom[ofs] >= lowerBoundsFrom[ofs] + lengths[ofs]) { idxesFrom[ofs] = lowerBoundsFrom[ofs]; idxesTo[ofs] = lowerBoundsTo[ofs]; ofs--; if (ofs < 0) { return(objTo); } } else { break; } } } }
private static T CloneStructInternal <T>(T obj, DeepCloneState state) // where T : struct { // no loops, no nulls, no inheritance var cloner = GetClonerForValueType <T>(); // safe ojbect if (cloner == null) { return(obj); } return(cloner(obj, state)); }
internal static T[] Clone1DimArrayClassInternal <T>(T[] objFrom, T[] objTo, DeepCloneState state) { if (objFrom == null || objTo == null) { return(null); } int num = Math.Min(objFrom.Length, objTo.Length); state.AddKnownRef(objFrom, objTo); for (int i = 0; i < num; i++) { objTo[i] = (T)DeepClonerGenerator.CloneClassInternal(objFrom[i], state); } return(objTo); }
internal static Array CloneAbstractArrayInternal(Array objFrom, Array objTo, DeepCloneState state, bool isDeep) { if (objFrom == null || objTo == null) { return(null); } int rank = objFrom.Rank; if (objTo.Rank == rank) { int[] array = Enumerable.Range(0, rank).Select(objFrom.GetLowerBound).ToArray(); int[] array2 = Enumerable.Range(0, rank).Select(objTo.GetLowerBound).ToArray(); int[] array3 = (from x in Enumerable.Range(0, rank) select Math.Min(objFrom.GetLength(x), objTo.GetLength(x))).ToArray(); int[] array4 = Enumerable.Range(0, rank).Select(objFrom.GetLowerBound).ToArray(); int[] array5 = Enumerable.Range(0, rank).Select(objTo.GetLowerBound).ToArray(); state.AddKnownRef(objFrom, objTo); while (true) { if (isDeep) { objTo.SetValue(DeepClonerGenerator.CloneClassInternal(objFrom.GetValue(array4), state), array5); } else { objTo.SetValue(objFrom.GetValue(array4), array5); } int num = rank - 1; while (true) { array4[num]++; array5[num]++; if (array4[num] < array[num] + array3[num]) { break; } array4[num] = array[num]; array5[num] = array2[num]; num--; if (num < 0) { return(objTo); } } } } throw new InvalidOperationException("Invalid rank of target array"); }
internal static T[] Clone1DimArrayClassInternal <T>(T[] obj, DeepCloneState state) { if (obj == null) { return(null); } int num = obj.Length; T[] array = new T[num]; state.AddKnownRef(obj, array); for (int i = 0; i < num; i++) { array[i] = (T)CloneClassInternal(obj[i], state); } return(array); }
internal static T[,] Clone2DimArrayInternal <T>(T[,] obj, DeepCloneState state) { if (obj == null) { return(null); } int length = obj.GetLength(0); int length2 = obj.GetLength(1); T[,] array = new T[length, length2]; state.AddKnownRef(obj, array); if (DeepClonerSafeTypes.CanNotCopyType(typeof(T), null)) { Array.Copy(obj, array, obj.Length); return(array); } if (typeof(T).IsValueType()) { Func <T, DeepCloneState, T> clonerForValueType = GetClonerForValueType <T>(); for (int i = 0; i < length; i++) { for (int j = 0; j < length2; j++) { T[,] array2 = array; int num = i; int num2 = j; T val = clonerForValueType(obj[i, j], state); array2[num, num2] = val; } } } else { for (int k = 0; k < length; k++) { for (int l = 0; l < length2; l++) { T[,] array3 = array; int num3 = k; int num4 = l; T obj2 = (T)CloneClassInternal(obj[k, l], state); array3[num3, num4] = obj2; } } } return(array); }
internal static T[] Clone1DimArrayClassInternal <T>(T[] objFrom, T[] objTo, DeepCloneState state) { // not null from called method, but will check it anyway if (objFrom == null || objTo == null) { return(null); } var l = Math.Min(objFrom.Length, objTo.Length); state.AddKnownRef(objFrom, objTo); for (var i = 0; i < l; i++) { objTo[i] = (T)DeepClonerGenerator.CloneClassInternal(objFrom[i], state); } return(objTo); }
internal static T[] Clone1DimArrayStructInternal <T>(T[] objFrom, T[] objTo, DeepCloneState state) { if (objFrom == null || objTo == null) { return(null); } int num = Math.Min(objFrom.Length, objTo.Length); state.AddKnownRef(objFrom, objTo); Func <T, DeepCloneState, T> clonerForValueType = DeepClonerGenerator.GetClonerForValueType <T>(); for (int i = 0; i < num; i++) { objTo[i] = clonerForValueType(objTo[i], state); } return(objTo); }
internal static T[] Clone1DimArrayStructInternal <T>(T[] obj, DeepCloneState state) { if (obj == null) { return(null); } int num = obj.Length; T[] array = new T[num]; state.AddKnownRef(obj, array); Func <T, DeepCloneState, T> clonerForValueType = GetClonerForValueType <T>(); for (int i = 0; i < num; i++) { array[i] = clonerForValueType(obj[i], state); } return(array); }
internal static T[] Clone1DimArrayClassInternal <T>(T[] obj, DeepCloneState state) { // not null from called method, but will check it anyway if (obj == null) { return(null); } var l = obj.Length; var outArray = new T[l]; state.AddKnownRef(obj, outArray); for (var i = 0; i < l; i++) { outArray[i] = (T)CloneClassInternal(obj[i], state); } return(outArray); }
internal static T[] Clone1DimArrayStructInternal <T>(T[] objFrom, T[] objTo, DeepCloneState state) { // not null from called method, but will check it anyway if (objFrom == null || objTo == null) { return(null); } var l = Math.Min(objFrom.Length, objTo.Length); state.AddKnownRef(objFrom, objTo); var cloner = DeepClonerGenerator.GetClonerForValueType <T>(); for (var i = 0; i < l; i++) { objTo[i] = cloner(objTo[i], state); } return(objTo); }
// relatively frequent case. specially handled internal static T[,] Clone2DimArrayInternal <T>(T[,] obj, DeepCloneState state) { // not null from called method, but will check it anyway if (obj == null) { return(null); } var l1 = obj.GetLength(0); var l2 = obj.GetLength(1); var outArray = new T[l1, l2]; state.AddKnownRef(obj, outArray); if (DeepClonerSafeTypes.IsTypeSafe(typeof(T), null)) { Array.Copy(obj, outArray, obj.Length); return(outArray); } if (typeof(T).IsValueType()) { var cloner = GetClonerForValueType <T>(); for (var i = 0; i < l1; i++) { for (var k = 0; k < l2; k++) { outArray[i, k] = cloner(obj[i, k], state); } } } else { for (var i = 0; i < l1; i++) { for (var k = 0; k < l2; k++) { outArray[i, k] = (T)CloneClassInternal(obj[i, k], state); } } } return(outArray); }
internal static object CloneClassInternal(object obj, DeepCloneState state) { if (obj == null) { return(null); } Func <object, DeepCloneState, object> func = (Func <object, DeepCloneState, object>)DeepClonerCache.GetOrAddClass(obj.GetType(), (Type t) => GenerateCloner(t, true)); if (func == null) { return(obj); } object knownRef = state.GetKnownRef(obj); if (knownRef != null) { return(knownRef); } return(func(obj, state)); }
internal static T[] Clone1DimArrayStructInternal <T>(T[] obj, DeepCloneState state) { // not null from called method, but will check it anyway if (obj == null) { return(null); } var l = obj.Length; var outArray = new T[l]; state.AddKnownRef(obj, outArray); var cloner = GetClonerForValueType <T>(); for (var i = 0; i < l; i++) { outArray[i] = cloner(obj[i], state); } return(outArray); }
// rare cases, very slow cloning. currently it's ok internal static Array CloneAbstractArrayInternal(Array obj, DeepCloneState state) { // not null from called method, but will check it anyway if (obj == null) { return(null); } var rank = obj.Rank; var lowerBounds = Enumerable.Range(0, rank).Select(obj.GetLowerBound).ToArray(); var lengths = Enumerable.Range(0, rank).Select(obj.GetLength).ToArray(); var idxes = Enumerable.Range(0, rank).Select(obj.GetLowerBound).ToArray(); var outArray = Array.CreateInstance(obj.GetType().GetElementType(), lengths, lowerBounds); state.AddKnownRef(obj, outArray); while (true) { outArray.SetValue(CloneClassInternal(obj.GetValue(idxes), state), idxes); var ofs = rank - 1; while (true) { idxes[ofs]++; if (idxes[ofs] >= lowerBounds[ofs] + lengths[ofs]) { idxes[ofs] = lowerBounds[ofs]; ofs--; if (ofs < 0) { return(outArray); } } else { break; } } } }