Hi Guys
NP68 Clone()
http://www.java2s.com/Tutorial/CSharp/0220__Data-Structure/Clonearraywithreferencedatainside.htm
I got the following program from above website.
Either with or without Clone() (highlighted in yellow), program is producing similar output. Anyone knows please explain the reason.
Thank you
using System;
class MyClass
{
public int Value = 5;
}
class MainClass
{
static void
{
MyClass[] orignalArray = new MyClass[3] { new MyClass(), new MyClass(), new MyClass() };
MyClass[] cloneArray = (MyClass[])orignalArray.Clone();
cloneArray[0].Value = 1;
cloneArray[1].Value = 2;
cloneArray[2].Value = 3;
foreach (MyClass a in orignalArray)
Console.WriteLine(a.Value);
foreach (MyClass a in cloneArray)
Console.WriteLine(a.Value);
}
}
/*
1
2
3
1
2
3
*/
Posted Sep 8, 2008, 4:14 PM
Thank you very much for explanation.
AlanPosted Sep 8, 2008, 4:03 PM
MemberwiseClone() is a method which all classes inherit from System.Object and which, as you say, produces a shallow copy of the object in question.
However, the method is 'protected' and so is not callable from outside the class, except by derived classes. If you want to make it available to outside code, then one way of doing so is to declare a public Clone() method which calls MemberwiseClone() internally. This in fact is how the Array.Clone() method is implemented:
public object Clone()
{
return base.MemberwiseClone();
}
So this is why the program doesn't compile when you try to replace Clone() with MemberwiseClone in the program in this thread - it's not accessible to code within MainClass because it's protected.
Posted Sep 8, 2008, 3:07 PM
http://www.codeproject.com/KB/cs/ShallowVsDeepCopy.aspx
Article in the above website says that:
“In C# and VB.NET, shallow copy is done by the object method MemberwiseClone()”
But in the above program instead of Clone() method if we use MemberwiseClone() program is not working. Please explain the reason.
AlanPosted Dec 12, 2007, 10:20 AM
If you could look at orignalArray in memory, then its three elements would contain pointers to where the three MyClass objects were stored, elsewhere, in the heap.
cloneArray would also contain the same three pointers and so these too would point to the same MyClass objects as orignalArray.
When a line like this is executed:
orignalArray[0].Value = 10;
The Value field of the MyClass object pointed to by the first element of orignalArray is set to 10. However, clonearray[0] also points to this same object and so, if you executed this line immediately afterwards, '10' would be printed to the console:
Console.WriteLine(cloneArray[0].Value);
This works the other way as well. When you execute this line:
cloneArray[0].Value = 1;
this automatically sets orignalArray[0].Value to 1 as well, because the first element of both arrays is pointing to the same MyClass object.
Exactly the same considerations apply to the other elements and so when you alter one, you alter the other and this is why they print out the same.
Posted Dec 12, 2007, 9:30 AM
Alan, I tried to understand your explanation. In the mean time it is highly appreciable if you could elaborate it some way.
AlanPosted Dec 12, 2007, 4:33 AM
Cloning works both ways :)
As both the original array and the cloned array contain references to the same MyClass objects then, if you change the value of those objects via the cloned array, then the same changes will be reflected in the original array.
Posted Dec 11, 2007, 8:41 PM
Just for curiosity I modified the above program. Output expected in the modified program is:
10
20
30
1
2
3
But it is producing:
1
2
3
1
2
3
Anyone knows please explain the reason.
using System;
class MyClass
{
public int Value = 5;
}
class MainClass
{
static voidMain ()
{
MyClass[] orignalArray = new MyClass[3] { new MyClass(), new MyClass(), new MyClass() }; //reference data
MyClass[] cloneArray = (MyClass[])orignalArray.Clone();
orignalArray[0].Value = 10;
orignalArray[1].Value = 20;
orignalArray[2].Value = 30;
cloneArray[0].Value = 1;
cloneArray[1].Value = 2;
cloneArray[2].Value = 3;
foreach (MyClass a in orignalArray)
Console.WriteLine(a.Value);
foreach (MyClass a in cloneArray)
Console.WriteLine(a.Value);
}
}
AlanPosted Dec 9, 2007, 12:55 PM
The Array.Clone() method produces what's called a 'shallow' copy.
This means that the contents of the elements are copied but, if those elements contain references to objects, the objects themselves are not copied as well.
So, if an Array of reference type objects (such as myClass) is cloned, the clone will contain references to the same objects as the original array did.
Thus, in this case, altering the Value field of the MyClass objects contained in cloneArray will be reflected in similar changes to the objects contained in orignalArray because, quite simply, they're the same objects :)