Array.Copy and Cloning an array don't seem to work differently

I

illegal.prime

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 = (TestPair)testPairs.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?

Thanks,
Novice
 
B

Bruce Wood

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 = (TestPair)testPairs.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()
{
...
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top