What’s the difference between the System.Array.CopyTo()
and System.Array.Clone()
?
As stated in many other answers both methods perform shallow copies of the array. However there are differences and recommendations that have not been addressed yet and that are highlighted in the following lists.
Characteristics of System.Array.Clone:
CopyTo
probably because it uses Object.MemberwiseClone;Characteristics of System.Array.CopyTo:
Clone
when copying to array of same type;int[]
array into an object[]
;object[]
array of boxed int
into an int[]
;int[]
into a long[]
.Stream[]
array into a MemoryStream[]
(if any element in source array is not convertible to MemoryStream
an exception is thrown).Also note, these methods are made available to support ICloneable and ICollection, so if you are dealing with variables of array types you should not use Clone
or CopyTo
and instead use Array.Copy or Array.ConstrainedCopy. The constrained copy assures that if the copy operation cannot complete successful then the target array state is not corrupted.
Both perform shallow copies as @PatrickDesjardins said (despite the many misled souls who think that CopyTo
does a deep copy).
However, CopyTo
allows you to copy one array to a specified index in the destination array, giving it significantly more flexibility.
One other difference not mentioned so far is that
Clone()
the destination array need not exist yet since a new one is created from scratch.CopyTo()
not only does the destination array need to already exist, it needs to be large enough to hold all the elements in the source array from the index you specify as the destination.Both are shallow copies. CopyTo method is not a deep copy. Check the following code :
public class TestClass1
{
public string a = "test1";
}
public static void ArrayCopyClone()
{
TestClass1 tc1 = new TestClass1();
TestClass1 tc2 = new TestClass1();
TestClass1[] arrtest1 = { tc1, tc2 };
TestClass1[] arrtest2 = new TestClass1[arrtest1.Length];
TestClass1[] arrtest3 = new TestClass1[arrtest1.Length];
arrtest1.CopyTo(arrtest2, 0);
arrtest3 = arrtest1.Clone() as TestClass1[];
Console.WriteLine(arrtest1[0].a);
Console.WriteLine(arrtest2[0].a);
Console.WriteLine(arrtest3[0].a);
arrtest1[0].a = "new";
Console.WriteLine(arrtest1[0].a);
Console.WriteLine(arrtest2[0].a);
Console.WriteLine(arrtest3[0].a);
}
/* Output is
test1
test1
test1
new
new
new */
The answers are confusing to me. When you say shallow copy, this means that they are still pointing to the same address. Which means, changing either one will change another as well.
So if I have A = [1,2,3,4] and I clone it and get B = [1,2,3,4]. Now, if I change B[0] = 9. This means that A will now be A = [9,2,3,4]. Is that correct?
Array.Clone()
would perform technically deep copy, when pass the array of int
or string to a method as a reference.
For example
int[] numbers = new int[] { -11, 12, -42, 0, 1, 90, 68, 6, -9 };
SortByAscending(numbers); // Sort the array in ascending order by clone the numbers array to local new array.
SortByDescending(numbers); // Same as Ascending order Clone
Even if the methods sort the array of numbers but it wont affect the actual reference passed to the sorting methods.i.e the number array will be in same unsorted initial format in line no 1.
Note: The Clone should be done in the sorting methods.