System.Array.CopyTo() 和 System.Array.Clone() 之间的区别

发布于 2024-07-06 10:50:26 字数 86 浏览 6 评论 0原文

System.Array.CopyTo()System.Array.Clone() 之间有什么区别?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

平生欢 2024-07-13 10:50:26

Clone()方法返回一个新数组(浅拷贝)对象,其中包含原始数组中的所有元素。 CopyTo()方法将元素复制到另一个现有数组中。 两者都执行浅复制。 浅拷贝意味着内容(每个数组元素)包含对与原始数组中的元素相同的对象的引用。 深层复制(这两种方法都不执行)将创建每个元素对象的新实例,从而产生不同但相同的对象。

所以区别是:

1- CopyTo require to have a destination array when Clone return a new array.
2- CopyTo let you specify an index (if required) to the destination array.

Edit:

删除错误的例子。

The Clone() method returns a new array (a shallow copy) object containing all the elements in the original array. The CopyTo() method copies the elements into another existing array. Both perform a shallow copy. A shallow copy means the contents (each array element) contains references to the same object as the elements in the original array. A deep copy (which neither of these methods performs) would create a new instance of each element's object, resulting in a different, yet identical object.

So the difference are :

1- CopyTo require to have a destination array when Clone return a new array.
2- CopyTo let you specify an index (if required) to the destination array.

Edit:

Remove the wrong example.

一桥轻雨一伞开 2024-07-13 10:50:26

到目前为止尚未提及的另一个区别是,

  • 使用 Clone() 时,目标数组不需要存在,因为新数组是从头开始创建的。
  • 使用 CopyTo() 不仅目标数组需要已经存在,而且它需要足够大以容纳源数组中您指定为目标的索引中的所有元素。

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.
无法言说的痛 2024-07-13 10:50:26

正如许多其他答案中所述,两种方法都执行 数组的浅拷贝。 然而,还存在尚未解决的差异和建议,并在以下列表中突出显示。

System.Array.Clone< 的特征/a>:

  • 使用 .NET 4.0 进行的测试表明,它CopyTo 慢,可能是因为它使用 Object.MemberwiseClone;
  • 需要将结果转换为适当的类型
  • 结果数组的长度与源数组的长度相同。

System.Array.CopyTo 的特征:

  • 复制到相同类型的数组时比克隆更快;
  • 它调用Array.Copy继承是能力,是最有用的:
    • 可以将值类型元素装箱为引用类型元素,例如将 int[] 数组复制到 object[] 中;
    • 可以将引用类型元素拆箱为值类型元素,例如,将装箱的 intobject[] 数组复制到 int[];
    • 可以对值类型执行扩展转换,例如将 int[] 复制到 long[]
    • 可以向下转换元素,例如,将 Stream[] 数组复制到 MemoryStream[](如果源数组中的任何元素无法转换为 MemoryStream 抛出异常)。
  • 允许将源复制到长度大于源的目标数组。

另请注意,这些方法可用于支持 ICloneableICollection< /a>,因此,如果您正在处理数组类型的变量,则不应使用 CloneCopyTo,而应使用 Array.CopyArray.ConstrainedCopy。 受限复制可确保如果复制操作无法成功完成,则目标阵列状态不会损坏。

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.

凉薄对峙 2024-07-13 10:50:26

正如 @PatrickDesjardins 所说,两者都执行浅复制(尽管许多人被误导,认为 CopyTo 执行深复制)。

但是,CopyTo 允许您将一个数组复制到目标数组中的指定索引,从而显着提高灵活性。

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.

夕嗳→ 2024-07-13 10:50:26
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"

来源

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

笑饮青盏花 2024-07-13 10:50:26

CopyTo() 和 Clone() 都进行浅复制。 Clone() 方法克隆原始数组。 它返回一个精确长度的数组。

另一方面,CopyTo() 将元素从原始数组复制到从指定目标数组索引开始的目标数组。 请注意,这会将元素添加到已经存在的数组中。

下面的代码将与说 CopyTo() 进行深层复制的帖子相矛盾:

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);
}

让我解释一下。 如果数组的元素是引用类型,则复制(Clone() 和 CopyTo() )将被复制到第一(顶部)级别。 但较低级别不会被复制。 如果我们还需要较低级别的副本,我们必须明确地进行。 这就是为什么在克隆或复制引用类型元素之后,克隆或复制数组中的每个元素都引用与原始数组中相应元素引用的相同内存位置。 这清楚地表明没有为较低级别创建单独的实例。 如果是这样,那么更改复制或克隆数组中任何元素的值都不会影响原始数组的相应元素。

我认为我的解释很详尽,但我找不到其他方法可以使其理解。

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.

幸福还没到 2024-07-13 10:50:26

当将 int 数组或字符串传递给方法作为引用时,Array.Clone() 将执行技术上的深度复制。

例如,

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

即使方法对数字数组进行排序,但它不会影响传递给排序方法的实际引用。即数字数组将在第 1 行中采用相同的未排序初始格式。

注意:克隆应该在排序方法中完成。

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.

在梵高的星空下 2024-07-13 10:50:26

Clone() 方法不提供对目标实例的引用,只是给您一个副本。
CopyTo() 方法将元素复制到现有实例中。

两者都没有给出目标实例的引用,并且正如许多成员所说,他们给出了没有引用的浅复制(幻象复制),这是关键。

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.

无所谓啦 2024-07-13 10:50:26

两者都是浅拷贝。 CopyTo 方法不是深层复制。
检查以下代码:

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

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 */
苏大泽ㄣ 2024-07-13 10:50:26

调用函数时,Array.Clone 不需要目标/目标数组可用,而 Array.CopyTo 则需要目标数组和索引。

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.

悍妇囚夫 2024-07-13 10:50:26

Clone() 用于仅复制数据/数组的结构,它不复制实际数据。

CopyTo() 复制结构和实际数据。

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.

初相遇 2024-07-13 10:50:26

请注意:使用 String[] 和 StringBuilder[] 之间是有区别的。

在 String 中 - 如果更改 String,我们复制(通过 CopyTo 或 Clone)的指向同一字符串的其他数组将不会更改,但原始 String 数组将指向新 String,但是,如果我们使用 StringBuilder在数组中,String指针不会改变,因此,它将影响我们为此数组所做的所有副本。 例如:

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
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文