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

c# .net arrays .net-2.0

91109 观看

12回复

4091 作者的声誉

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

作者: Mister Dev 的来源 发布者: 2008 年 10 月 13 日

回应 (12)


47

90865 作者的声誉

决定

克隆()方法返回一个新的数组包含原始阵列中的所有元件(浅表副本)对象。所述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.
编辑:

删除错误的示例。

作者: Patrick Desjardins 发布者: 13.10.2008 06:20

21

117788 作者的声誉

正如@PatrickDesjardins所说,两者都执行浅拷贝(尽管许多误导的灵魂认为这CopyTo是深刻的复制)。

但是,CopyTo允许您将一个数组复制到目标数组中的指定索引,从而为其提供更大的灵活性。

作者: FlySwat 发布者: 13.10.2008 06:23

25

288827 作者的声誉

到目前为止没有提到的另一个区别是

  • Clone()目标阵列,因为一个新的从头开始创建不必还不存在。
  • CopyTo()不仅目标阵列需要已经存在,它需要足够大,以容纳从您指定为目标的索引源阵列中的所有元素。
作者: Michael Burr 发布者: 13.10.2008 06:45

7

885 作者的声誉

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"

来源

作者: GenZiy 发布者: 06.11.2009 08:10

-1

0 作者的声誉

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

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

作者: user257390 发布者: 23.01.2010 12:49

2

117 作者的声誉

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())都将构成第一个(顶层)级别。但是较低级别不会被复制。如果我们还需要较低级别的副本,我们必须明确地做。这就是为什么在克隆或复制引用类型元素之后,Cloned或Copied数组中的每个元素都引用与原始数组中相应元素引用的相同内存位置。这清楚地表明没有为较低级别创建单独的实例。如果是这样,那么更改Copied或Cloned数组中任何元素的值将不会对原始数组的相应元素产生影响。

我认为我的解释是详尽无遗的,但我发现没有其他方法可以理解。

作者: Prasad 发布者: 14.03.2011 07:31

0

3 作者的声誉

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

两者都没有给出目标实例的引用,并且许多成员说他们给出浅拷贝(错觉拷贝)而没有引用这是关键。

作者: Mohammad Ahmed 发布者: 29.02.2012 11:19

18

45162 作者的声誉

如许多其他答案中所述,两种方法都执行阵列的浅拷贝。但是,有些差异和建议尚未解决,并在以下列表中突出显示。

特点System.Array.Clone

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

特点System.Array.CopyTo

  • Clone复制到相同类型的数组更快 ;
  • 它调用Array.Copy继承功能,是最有用的功能:
    • 可以将值类型元素框值转换为引用类型元素,例如,将int[]数组复制到object[];
    • 可以将unbox引用类型元素转换为值类型元素,例如,将一个object[]盒装数组复制int到一个int[];
    • 可以对值类型执行扩展转换,例如,将a复制int[]到a long[]
    • 可以向下转换元素,例如,将Stream[]数组复制到一个MemoryStream[](如果源数组中的任何元素不能转换为MemoryStream异常,则抛出)。
  • 允许将源复制到长度大于源的目标阵列。

还要注意,这些方法提供支持ICloneableICollection,因此,如果你正在处理,你不应该使用数组类型的变量CloneCopyTo转而使用Array.CopyArray.ConstrainedCopy。受约束的副本确保如果复制操作无法完成,则目标阵列状态不会被破坏。

作者: João Angelo 发布者: 27.08.2012 12:12

0

439 作者的声誉

答案让我感到困惑。当你说浅拷贝时,这意味着他们仍然指向同一个地址。这意味着,更改任何一个也会改变另一个。

所以,如果我有A = [1,2,3,4]并且我克隆它并得到B = [1,2,3,4]。现在,如果我改变B [0] = 9.这意味着A现在将是A = [9,2,3,4]。那是对的吗?

作者: Stranger 发布者: 09.06.2013 05:21

-2

452 作者的声誉

请注意:使用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
}
作者: inbaly 发布者: 09.12.2013 12:06

0

116 作者的声誉

两者都是浅色副本。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 */
作者: Nikhil Redij 发布者: 13.04.2017 02:50

0

76 作者的声誉

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

作者: Aikansh Mann 发布者: 17.07.2019 09:33
32x32