Deep Copy with Array
Why doesn't ICloneable
's Clone
method return a deep copy?
Here is some sample code:
class A : ICloneable
{
public int x = 2;
public A(int x)
{
this.x = x;
}
public A copy()
{
A a = new A(this.x);
return a;
}
public object Clone()
{
A a = new A(this.x);
return a;
}
}
In the Main
method :
A[] Array1 = new A[4] ;
Array1[0] = new A(0);
Array1[1] = new A(1);
Array1[2] = new A(2);
Array1[3] = ne开发者_开发知识库w A(3);
A[] Array2 = new A[10];
Array. Copy(Array1, Array2, 4);
Array2[2].x = 11;
for (int i = 0; i < 4; i++)
Console.WriteLine($"Index {i} value: {Array1[i].x}");
Remembering that I've only changed element index 2 in Array2
, here is the output from the code above, listing the values in Array1
:
Index 0 value: 0
Index 1 value: 1
Index 2 value: 11
Index 3 value: 3
Index 2 in Array1
has 11
even though I changed it in Array2
and class A
implements ICloneable
!
What then is the benefit of Array
implementing ICloneable
?
From http://msdn.microsoft.com/en-us/library/k4yx47a1.aspx:
"If sourceArray and destinationArray are both reference-type arrays or are both arrays of type Object, a shallow copy is performed. A shallow copy of an Array is a new Array containing references to the same elements as the original Array. The elements themselves or anything referenced by the elements are not copied"
There may be a better method than this, but one technique you could use is:
A[] array2 = array1.Select (a =>(A)a.Clone()).ToArray();
Array.Copy copies the values of the array, in this case, references. There is nothing in the documentation of Array.Copy() that indicates a check for classes that implement IClonable and call Clone() instead. You will need to loop through the array and call Clone() yourself.
BTW, yes, IClonable kind of sucks.
Array.Copy()
does not use ICloneable. It simply copies values stored in each cell (which in this case are references to your A objects)
Ani's answer uses LINQ thus does not work for C# 2.0, however a same method can be done using the Array class's ConvertAll
method:
A[] Array2 = Array.ConvertAll(Array1,a => (A)a.Clone());
精彩评论