Hi Guys
NP89 ICloneable interface
http://www.java2s.com/Code/CSharp/Language-Basics/DemonstrateICloneable.htm
I got following program from the above website. It demonstrates ICloneable interface.
What is the purpose of defining X o = new X(x);. Because without defining
X o = new X(x); program is producing same result. Next program demonstrates that.
Anyone knows please explain the reason.
Thank you
using System;
class X
{
public int a;
public X(int x) { a = x; }
}
class Test : ICloneable
{
public X o;
public int b;
public Test(int x, int y)
{
o = new X(x);
b = y;
}
public void show(string name)
{
Console.Write(name + " values are ");
Console.WriteLine("o.a: {0}, b: {1}", o.a, b);
Console.WriteLine();
}
// Make a deep copy of the invoking object.
public object Clone()
{
Test temp = new Test(o.a, b);
return temp;
}
}
public class CloneDemo
{
public static void
{
Test ob1 = new Test(10, 20);
ob1.show("ob1");
Console.WriteLine("Make ob2 a clone of ob1.");
Test ob2 = (Test)ob1.Clone();
ob2.show("ob2");
Console.WriteLine("Changing ob1.o.a to 99 and ob1.b to 88.");
ob1.o.a = 99;
ob1.b = 88;
ob1.show("ob1");
ob2.show("ob2");
}
}
using System;
/*
class X
{
public int a;
public X(int x) { a = x; }
}
*/
class Test //: ICloneable
{
//public X o;
public int a;
public int b;
public Test(int x, int y)
{
//o = new X(x);
a = x;
b = y;
}
public void show(string name)
{
Console.Write(name + " values are ");
Console.WriteLine("a: {0}, b: {1}", a, b);
Console.WriteLine();
}
// Make a deep copy of the invoking object.
public object Clone()
{
Test temp = new Test(a, b);
return temp;
}
}
public class CloneDemo
{
public static void
{
Test ob1 = new Test(10, 20);
ob1.show("ob1");
Console.WriteLine("Make ob2 a clone of ob1.");
Test ob2 = (Test)ob1.Clone();
ob2.show("ob2");
Console.WriteLine("Changing ob1.o.a to 99 and ob1.b to 88.");
ob1.a = 99;
ob1.b = 88;
ob1.show("ob1");
ob2.show("ob2");
}
}
Posted Sep 11, 2008, 5:08 PM
Thank you for your help, Alan.
AlanPosted Sep 11, 2008, 3:33 PM
Ah, the problem is that we haven't inserted a paramterless constructor for the Test class. Also we'll need to reproduce in the Clone() method what the constructor with two parameters is doing.
Assuming it's the first program in this thread we're running, this should now work as it originally did (new or changed code in red):
using System;
class X
{
public int a;
public X(int x) { a = x; }
}
class Test : ICloneable
{
public X o;
public int b;
public Test()
{
public Test(int x, int y)
{
o = new X(x);
b = y;
}
public void show(string name)
{
Console.Write(name + " values are ");
Console.WriteLine("o.a: {0}, b: {1}", o.a, b);
Console.WriteLine();
}
// Make a deep copy of the invoking object.
public object Clone()
{
Test temp = new Test();
temp.o = new X(o.a);
temp.b = b;
return temp;
}
}
public class CloneDemo
{
public static voidMain ()
{
Test ob1 = new Test(10, 20);
ob1.show("ob1");
Console.WriteLine("Make ob2 a clone of ob1.");
Test ob2 = (Test)ob1.Clone();
ob2.show("ob2");
Console.WriteLine("Changing ob1.o.a to 99 and ob1.b to 88.");
ob1.o.a = 99;
ob1.b = 88;
ob1.show("ob1");
ob2.show("ob2");
}
}
Posted Sep 11, 2008, 10:41 AM
In addition to your method I tried following way as well but program is not executing.
public object Clone()
{
Test temp = new Test();
temp.o.a = this.o.a;
temp.b = this.b;
return temp;
}
AlanPosted Sep 11, 2008, 10:13 AM
It's not correct to do that because 'this' would refer to the current instance of Test, not the clone.
However, this would work:
public object Clone()
{
Test temp = new Test();
temp.o = o.a;
temp.b = b;
return temp;
}
Posted Sep 11, 2008, 9:50 AM
There is a following code in the above program (highlighted in brown)
public object Clone()
{
Test temp = new Test(o.a, b);
return temp;
}
In this program why it is not correct to say the above code as follows:
public object Clone()
{
Test temp = new Test();
this.o.a = a;
this.b = b;
return temp;
}
Because there is a another program even though constructor in the main program is loaded with, same constructor in the implementation of Clone() method is empty. Please see
NP91 Clone() method.
http://www.c-sharpcorner.com/Forums/ShowMessages.aspx?ThreadID=39637
Posted Sep 10, 2008, 4:16 PM
Yes, my doubt is clear. Thank you for your explanation, Alan.
AlanPosted Sep 10, 2008, 3:11 PM
If a class contained only value type fields (as X does), then there would be no distinction between a shallow and deep copy and so a clone would be independent of the original.
Is that the point you were trying to establish, Maha?
Posted Sep 10, 2008, 10:00 AM
'Deep copy’ cloning produces exect independent copy, whereas 'shallow copy' cloning produces exect copy but not necessarily independent.
Because in the 'shallow copy' program object 'ob2' which is referring to b value (20) is remaining the same even though we have changed the ob1 referring to b value (88)
I wish to know whether my understanding is correct. Please confirm it.
class X
{
public int a;
public X(int x) { a = x; }
}
AlanPosted Sep 10, 2008, 8:41 AM
Yes, that's right Maha.
A deep copy is independent in the sense that all reference type fields of the clone point to different objects, but with identical state, to the original.
In the case of a shallow copy, all reference type fields of the clone point to the same object as the original.
Posted Sep 10, 2008, 8:27 AM
'Deep copy’ cloning produces exect independent copy, whereas 'shallow copy' cloning produces exect copy but not independent.
I wish to know whether my understanding is correct. Please confirm it.
AlanPosted Mar 26, 2008, 1:41 PM
ob1.ShallowCopy returns a System.Object (i.e. object type in C#) which actually refers to a Test object.
However, the compiler doesn't know this and so won't allow that line unless you cast it to Test first.
Posted Mar 26, 2008, 11:49 AM
Test ob2 = (Test)ob1.ShallowCopy();
ob1 type is Test why it is necessary to cast again. Anyone knows please explain the reason.
AlanPosted Mar 21, 2008, 3:00 PM
I think the reason is to demonstrate that you're making a 'deep' copy of the object.
So, not only is the object reference 'o' copied but also the object to which it refers. The object in this case is a boxed int - i.e. an int which has been copied to the heap and housed within a special type so that an object variable can refer to it.
If a 'shallow copy'had been made, then the object reference 'o' would have been copied but not the boxed int to which it refers. For example:
using System;
class X
{
public int a;
public X(int x) { a = x; }
}
class Test : ICloneable
{
public X o;
public int b;
public Test(int x, int y)
{
o = new X(x);
b = y;
}
public void show(string name)
{
Console.Write(name + " values are ");
Console.WriteLine("o.a: {0}, b: {1}", o.a, b);
Console.WriteLine();
}
// Make a deep copy of the invoking object.
public object Clone()
{
Test temp = new Test(o.a, b);
return temp;
}
// Make a shallow copy of the invoking object
public object ShallowCopy()
{
return this.MemberwiseClone();
}
}
public class CloneDemo
{
public static voidMain ()
{
Test ob1 = new Test(10, 20);
ob1.show("ob1");
Console.WriteLine("Make ob2 a shallow copy of ob1.");
Test ob2 = (Test)ob1.ShallowCopy();
ob2.show("ob2");
Console.WriteLine("Changing ob1.o.a to 99 and ob1.b to 88.");
ob1.o.a = 99;
ob1.b = 88;
ob1.show("ob1");
ob2.show("ob2");
}
}