在C#中,Array.ToArray()执行深拷贝吗?

8

这应该是一个相当基本的问题,但我一直有些难以找到明确的答案。

当你有一个值数组并使用 .ToArray() 方法时,它会创建一个深层复制还是浅层复制?


在我写了一个快速测试之前,我实际上在互联网上寻找这个问题的答案(这并不像使用Google那么快)。我认为问题被评为-1分是因为你没有理解深拷贝、浅拷贝和对象引用之间的区别(你可能所指的是浅拷贝)。 - capn
2个回答

11

不需要。

你可以编写一个小程序来进行验证,这很容易。


+1. 注意,如果它是结构体数组,它将复制值(仍然是浅拷贝)。 - Alexei Levenkov
1
我刚刚创建了一个包含3个元素的string[]小程序,然后我创建了一个新数组并使用origArray.ToArray()进行赋值。接着我改变了新数组中的一个元素,并打印出了两个数组,它们是不同的。这难道不意味着这是一个深拷贝吗?我错过了什么吗? - hrh
2
在C#中没有内置的方法来进行深拷贝,所以你对“深拷贝”的定义可能是不寻常的。考虑提出新问题:“什么是深拷贝,这是我的理解...”(不要忘记清楚地解释你的理解,以便其他人可以确认/评论你的理解哪些部分是错误或非传统的)。 - Alexei Levenkov
谢谢,我会先进行更多的研究(也许会问另一个问题)。我的理解是,浅拷贝会使原始对象和其克隆体引用同一对象,因此如果我更改新对象,它也会更改原始对象所看到的内容。然后我认为深拷贝不会这样做(它会创建一个全新的对象)。 - hrh
3
@hrh,你的测试显示出现这种情况的原因是C#中的字符串是不可变的。实际上,你所做的是将一个新的字符串赋值给另一个数组中该索引处的元素。如果要进行深拷贝测试,请创建一个自己的类数组,并使用引用类型变量修改其中一个数组中的一个元素上的变量,你会发现在两个数组中都进行了修改。 - markmnl
3
这个答案可能需要更多的解释和细节。 - CervEd

7

严格来讲,ICollection.ToArray() 方法会创建一个新的 T[] 数组,并使用 Array.CopyTo() 方法将原始集合中的每个元素分配给新数组。

注意:

如果 T 是值类型,则会分配值而不是引用。这将表现为我们所期望的 "深拷贝"。

int[] foo = { 1, 2, 3, 4 };
int[] bar = foo.ToArray();

for (int i = 0; i < foo.Length; i++) foo[i] += 10;

Console.WriteLine(string.Join(',', foo)); // 11, 12, 13, 14
Console.WriteLine(string.Join(',', bar)); // 1, 2, 3, 4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接