[c#] Difference between the System.Array.CopyTo() and System.Array.Clone()

What’s the difference between the System.Array.CopyTo() and System.Array.Clone()?

This question is related to c# .net arrays .net-2.0

The answer is


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.


Array.Clone doesn't require a target/destination array to be available when calling the function, whereas Array.CopyTo requires a destination array and an index.


The Clone() method don't give reference to the target instance just give you a copy. the CopyTo() method copies the elements into an existing instance.

Both don't give the reference of the target instance and as many members says they give shallow copy (illusion copy) without reference this is the key.


Clone() is used to copy only structure of data/array it doesn't copy the actual data.

CopyTo() copies the structure as well as actual data.


Both CopyTo() and Clone() make shallow copy. Clone() method makes a clone of the original array. It returns an exact length array.

On the other hand, CopyTo() copies the elements from the original array to the destination array starting at the specified destination array index. Note that, this adds elements to an already existing array.

The following code will contradict the postings saying that CopyTo() makes a deep copy:

public class Test
{
public string s;
}

// Write Main() method and within it call test()

private void test()
{
Test[] array = new Test[1];
array[0] = new Test();
array[0].s = "ORIGINAL";

Test[] copy = new Test[1];
array.CopyTo(copy, 0);

// Next line displays "ORIGINAL"
MessageBox.Show("array[0].s = " + array[0].s);
copy[0].s = "CHANGED";

// Next line displays "CHANGED", showing that
// changing the copy also changes the original.
MessageBox.Show("array[0].s = " + array[0].s);
}

Let me explain it a bit. If the elements of the array are of reference types, then the copy (both for Clone() and CopyTo()) will be made upto the first(top) level. But the lower level doesn't get copied. If we need copy of lower level also, we have to do it explicitly. That's why after Cloning or Copying of reference type elements, each element in the Cloned or Copied array refers to the same memory location as referred by the corresponding element in the original array. This clearly indicates that no separate instance is created for lower level. And if it were so then changing the value of any element in the Copied or Cloned array would not have effect in the corresponding element of the original array.

I think that my explanation is exhaustive but I found no other way to make it understandable.


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

  • with Clone() the destination array need not exist yet since a new one is created from scratch.
  • with 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.

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:

  • Tests, using .NET 4.0, show that it is slower than CopyTo probably because it uses Object.MemberwiseClone;
  • Requires casting the result to the appropriate type;
  • The resulting array has the same length as the source.

Characteristics of System.Array.CopyTo:

  • Is faster than Clone when copying to array of same type;
  • It calls into Array.Copy inheriting is capabilities, being the most useful ones:
    • Can box value type elements into reference type elements, for example, copying an int[] array into an object[];
    • Can unbox reference type elements into value type elements, for example, copying a object[] array of boxed int into an int[];
    • Can perform widening conversions on value types, for example, copying a int[] into a long[].
    • Can downcast elements, for example, copying a Stream[] array into a MemoryStream[] (if any element in source array is not convertible to MemoryStream an exception is thrown).
  • Allows to copy the source to a target array that has a length greater than the source.

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.


Clone() is used to copy only structure of data/array it doesn't copy the actual data.

CopyTo() copies the structure as well as actual data.


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 */

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:

  • Tests, using .NET 4.0, show that it is slower than CopyTo probably because it uses Object.MemberwiseClone;
  • Requires casting the result to the appropriate type;
  • The resulting array has the same length as the source.

Characteristics of System.Array.CopyTo:

  • Is faster than Clone when copying to array of same type;
  • It calls into Array.Copy inheriting is capabilities, being the most useful ones:
    • Can box value type elements into reference type elements, for example, copying an int[] array into an object[];
    • Can unbox reference type elements into value type elements, for example, copying a object[] array of boxed int into an int[];
    • Can perform widening conversions on value types, for example, copying a int[] into a long[].
    • Can downcast elements, for example, copying a Stream[] array into a MemoryStream[] (if any element in source array is not convertible to MemoryStream an exception is thrown).
  • Allows to copy the source to a target array that has a length greater than the source.

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.


Array.Clone doesn't require a target/destination array to be available when calling the function, whereas Array.CopyTo requires a destination array and an index.


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.


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 */

object[] myarray = new object[] { "one", 2, "three", 4, "really big number", 2324573984927361 };

//create shallow copy by CopyTo
//You have to instantiate your new array first
object[] myarray2 = new object[myarray.Length];
//but then you can specify how many members of original array you would like to copy 
myarray.CopyTo(myarray2, 0);

//create shallow copy by Clone
object[] myarray1;
//here you don't need to instantiate array, 
//but all elements of the original array will be copied
myarray1 = myarray.Clone() as object[];

//if not sure that we create a shalow copy lets test it
myarray[0] = 0;
Console.WriteLine(myarray[0]);// print 0
Console.WriteLine(myarray1[0]);//print "one"
Console.WriteLine(myarray2[0]);//print "one"

the source


One other difference not mentioned so far is that

  • with Clone() the destination array need not exist yet since a new one is created from scratch.
  • with 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.

object[] myarray = new object[] { "one", 2, "three", 4, "really big number", 2324573984927361 };

//create shallow copy by CopyTo
//You have to instantiate your new array first
object[] myarray2 = new object[myarray.Length];
//but then you can specify how many members of original array you would like to copy 
myarray.CopyTo(myarray2, 0);

//create shallow copy by Clone
object[] myarray1;
//here you don't need to instantiate array, 
//but all elements of the original array will be copied
myarray1 = myarray.Clone() as object[];

//if not sure that we create a shalow copy lets test it
myarray[0] = 0;
Console.WriteLine(myarray[0]);// print 0
Console.WriteLine(myarray1[0]);//print "one"
Console.WriteLine(myarray2[0]);//print "one"

the source


Please note: There is a difference between using String[] to StringBuilder[].

In String - if you change the String, the other arrays we have copied (by CopyTo or Clone) that points to the same string will not change, but the original String array will point to a new String, however, if we use a StringBuilder in an array, the String pointer will not change, therefore, it will affect all the copies we have made for this array. For instance:

public void test()
{
    StringBuilder[] sArrOr = new StringBuilder[1];
    sArrOr[0] = new StringBuilder();
    sArrOr[0].Append("hello");
    StringBuilder[] sArrClone = (StringBuilder[])sArrOr.Clone();
    StringBuilder[] sArrCopyTo = new StringBuilder[1];
    sArrOr.CopyTo(sArrCopyTo,0);
    sArrOr[0].Append(" world");

    Console.WriteLine(sArrOr[0] + " " + sArrClone[0] + " " + sArrCopyTo[0]);
    //Outputs: hello world hello world hello world

    //Same result in int[] as using String[]
    int[] iArrOr = new int[2];
    iArrOr[0] = 0;
    iArrOr[1] = 1;
    int[] iArrCopyTo = new int[2];
    iArrOr.CopyTo(iArrCopyTo,0);
    int[] iArrClone = (int[])iArrOr.Clone();
    iArrOr[0]++;
    Console.WriteLine(iArrOr[0] + " " + iArrClone[0] + " " + iArrCopyTo[0]);
   // Output: 1 0 0
}

One other difference not mentioned so far is that

  • with Clone() the destination array need not exist yet since a new one is created from scratch.
  • with 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.

Please note: There is a difference between using String[] to StringBuilder[].

In String - if you change the String, the other arrays we have copied (by CopyTo or Clone) that points to the same string will not change, but the original String array will point to a new String, however, if we use a StringBuilder in an array, the String pointer will not change, therefore, it will affect all the copies we have made for this array. For instance:

public void test()
{
    StringBuilder[] sArrOr = new StringBuilder[1];
    sArrOr[0] = new StringBuilder();
    sArrOr[0].Append("hello");
    StringBuilder[] sArrClone = (StringBuilder[])sArrOr.Clone();
    StringBuilder[] sArrCopyTo = new StringBuilder[1];
    sArrOr.CopyTo(sArrCopyTo,0);
    sArrOr[0].Append(" world");

    Console.WriteLine(sArrOr[0] + " " + sArrClone[0] + " " + sArrCopyTo[0]);
    //Outputs: hello world hello world hello world

    //Same result in int[] as using String[]
    int[] iArrOr = new int[2];
    iArrOr[0] = 0;
    iArrOr[1] = 1;
    int[] iArrCopyTo = new int[2];
    iArrOr.CopyTo(iArrCopyTo,0);
    int[] iArrClone = (int[])iArrOr.Clone();
    iArrOr[0]++;
    Console.WriteLine(iArrOr[0] + " " + iArrClone[0] + " " + iArrCopyTo[0]);
   // Output: 1 0 0
}

One other difference not mentioned so far is that

  • with Clone() the destination array need not exist yet since a new one is created from scratch.
  • with 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 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.


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?


The Clone() method don't give reference to the target instance just give you a copy. the CopyTo() method copies the elements into an existing instance.

Both don't give the reference of the target instance and as many members says they give shallow copy (illusion copy) without reference this is the key.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to .net-2.0

"This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded" Debugging doesn't start How to show text in combobox when no item selected? Compression/Decompression string with C# Best way to Bulk Insert from a C# DataTable Get domain name How to open a new form from another form Maximize a window programmatically and prevent the user from changing the windows state How should you diagnose the error SEHException - External component has thrown an exception Editing dictionary values in a foreach loop