将一个2D数组复制到另一个2D数组

29
我用这段代码将一个二维数组复制到另一个二维数组:
Array.Copy(teamPerformance, 0,tempPerformance,0, teamPerformance.Length);

然而,当我更改tempPerformance中的一些数据时,这些更改也适用于teamPerformance
我应该怎么做才能控制这个问题?

5个回答

70

你需要使用 Clone() 方法

double[,] arr = 
{
   {1, 2},
   {3, 4}
};
double[,] copy = arr.Clone() as double[,];
copy[0, 0] = 2;
//it really copies the values, not a shallow copy, 
//after:
//arr[0,0] will be 1
//copy[0,0] will be 2

我更喜欢这个答案。此外,我建议赋值看起来像这样:double[,] copy = (double[,])arr.Clone(); - zumalifeguard
8
Clone()方法创建一个浅表副本,将每个数组元素的值复制到新数组中。对于值类型,这实际上创建了一个深层副本,但对于对象数组或数组的数组(例如dasblinkenlight的示例),它不起作用。演示 - Calvin Li
虽然这样做是可行的,但是当你有一个值类型的多维数组,比如上面的例子中的double时,Array.Copy()也会执行完全相同的操作。当你有一个锯齿状数组(double[][]而不是double[,])并且需要克隆内部数组时,这非常有用。OP很可能指的是一个锯齿状数组或一个引用类型的多维数组。 - Amal K

21

这是正确的:Array.Copy 执行浅复制,因此内部维度中的数组实例将通过引用进行复制。您可以使用 LINQ 进行复制,像这样:

var copy2d = orig2d.Select(a => a.ToArray()).ToArray();

这里有一个在ideone上的演示(点击此处).


6
这显然只适用于锯齿数组,因为 Select() 并未针对二维数组定义。 - GSerg

3
据我理解阅读问题,我假设数组中填充的是引用类型,但C#没有提供“仅复制”引用类型的方法。它只会复制到对象的引用(因此,两个东西将指向同一个东西)。
因此,将引用类型放入数组中,然后复制数组,将不会“只”复制引用类型(因为C#不能在数组内或外执行此操作)。
这就是为什么这里给出的0个答案都无法解决问题的原因。Sheng的答案是正确的(但无法解决问题),可能需要更多的解释。
如果您想复制引用类型,则应查找确切的方法。例如,将它们转换为和从JSON,或者自己制作一个复制方法,可能使用反射。

1
准确地说,除非您告诉C#如何执行深度复制,否则无法执行深度复制。 - Paul Childs

3
根据微软(http://msdn.microsoft.com/en-us/library/z50k9bft.aspx)的说法:
如果sourceArray和destinationArray都是引用类型数组或者都是Object类型的数组,则执行浅复制。数组的浅复制是一个新的数组,其中包含对原始数组中相同元素的引用。元素本身或被元素引用的任何内容都不会被复制。相比之下,数组的深复制会复制元素以及元素直接或间接引用的所有内容。

0
您还可以使用:
int[] copy = new int[old.Length];
Buffer.BlockCopy(old, 0, copy, 0, old.Length * 4];

请注意,您需要知道要复制的字节数。除此之外,我非常确信这个操作非常高效。

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