(E-Mail Removed) wrote:
> I would like to have an array of objects (whose class I define) and
> then just invoke either:
> MyClass [] clonedArray = (MyClass[]) myArray.Clone();
> OR
> Array.Copy(myArray, clonedArray, myArray.Length);
>
> and have an array of cloned objects (i.e. the new array of objects
> aren't the objects contained in my original array). But instead it
> seems necessary for me to have to iterate over my entire array and
> individually clone each element in the array. I thought at least
> Array.Copy would do this for me. Does anyone know why it doesn't or if
> I'm missing something that would make this idea work? Or do I actually
> have to manually iterate over my array to achieve this?
>
> Here is the test code so you can see what I mean:
>
> class TestPair : ICloneable
> {
> public string a;
> public string b;
>
> public TestPair (string aParam, string bParam)
> {
> a = aParam;
> b = bParam;
> }
>
> public object Clone()
> {
> return new TestPair(a, b);
> }
> }
>
> public static void TestCloneOfClassWithPair()
> {
> TestPair testCloneOfPair1 = new TestPair("blah", "meh");
>
> TestPair [] testPairs = new TestPair[1];
> testPairs[0] = testCloneOfPair1;
>
> // the following tries to use the Clone method of the array
> //TestPair [] testCloneOfPairs = (TestPair [])testPairs.Clone();
> // the following tries using Array.Clone
> /*TestPair [] testCloneOfPairs = new TestPair[testPairs.Length];
> Array.Copy(testPairs, testCloneOfPairs, testCloneOfPairs.Length);*/
> // Only the following actually succeeds in giving me an array of
> elements that don't reference the original array
> TestPair [] testCloneOfPairs = new TestPair[testPairs.Length];
> for (int i = 0;i < testPairs.Length;i++)
> {
> testCloneOfPairs[i] = (TestPair)testPairs[i].Clone();
> }
>
> if (testPairs[0] == testCloneOfPairs[0])
> Trace.WriteLine("same object is referenced");
>
> testCloneOfPairs[0].a = "new value";
> Trace.WriteLine("testPairs - a: "+testPairs[0].a+" b:
> "+testPairs[0].b);
> }
>
> Suggestions of why neither of the two other techniques succeed?
By definition, default copies / clones are all shallow. You want a deep
copy.
In order to achieve this you have to either:
a) Define a static method in your TestPair class that clones an array:
public static TestPair[] CloneArray(TestPair[])
{
...
}
and then TestPair[] clone = TestPair.CloneArray(original);
or b) Define a whole new class that is a collection of TestPairs and
write a Clone method for it:
public class TestPairCollection ...
{
public object Clone()
{
...
}
}