The ICloneable Interface


By implementing the ICloneable interface, you enable a copy of an object to be made. ICloneable defines only one method, Clone( ), which is shown here:

 object Clone( )

This method makes a copy of the invoking object. How you implement Clone( ) determines how the copy is made. In general, there are two types of copies: deep and shallow. When a deep copy is made, the copy and original are completely independent. Thus, if the original object contained a reference to another object O, then a copy of O will also be made. In a shallow copy, members are copied, but objects referred to by members are not. If an object refers to some other object O, then after a shallow copy, both the copy and the original will refer to the same O, and any changes to O affect both the copy and the original. Usually, you will implement Clone( ) so that it performs a deep copy. Shallow copies can be made by using MemberwiseClone( ), which is defined by Object.

Here is an example that illustrates ICloneable. It creates a class called Test that contains a reference to a class called X. Test uses Clone( ) to create a deep copy.

 // Demonstrate ICloneable. 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);   }   // Make a deep copy of the invoking object.   public object Clone() {     Test temp = new Test(o.a, b);     return temp;   } } class CloneDemo {   public static void Main() {     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");   } }

The output is shown here:

 ob1 values are o.a: 10, b: 20 Make ob2 a clone of ob1. ob2 values are o.a: 10, b: 20 Changing ob1.o.a to 99 and ob1.b to 88. ob1 values are o.a: 99, b: 88 ob2 values are o.a: 10, b: 20

As the output shows, ob2 is a clone of ob1, but ob1 and ob2 are completely separate objects. Changing one does not affect the other. This is accomplished by allocating a new X object for the copy and giving it the same value as the X object in the original.

To implement a shallow copy, simply have Clone( ) call MemberwiseClone( ) defined by Object. For example, try changing Clone( ) in the preceding program as shown here:

 // Make a shallow copy of the invoking object. public object Clone() {   Test temp = (Test) MemberwiseClone();   return temp; }

After you make this change, the output of the program will look like this:

 ob1 values are o.a: 10, b: 20 Make ob2 a clone of ob1. ob2 values are o.a: 10, b: 20 Changing ob1.o.a to 99 and ob1.b to 88. ob1 values are o.a: 99, b: 88 ob2 values are o.a: 99, b: 20

Notice that o in ob1 and o in ob2 both refer to the same X object. Changing one affects both. Of course, the int field b in each is still separate because the value types are not accessed via references.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net