Shallow Copy Vs Deep Copy

Shallow Copy


For instances of value types, the '=' assignment operator copies the state of the source object to the destination object. The copy is done byte-by-byte. Simple object copying by members is achievable through the method MemberwiseClone() inherited from System.Object. This is a protected method and the copying supplied by it is known as shallow copying (it copies the reference but not the referred object; thus the original object and its copy/clone refer to the same object).

Steps:

  • Create a new object 
  • Copy the non-static fields of the current object to the new object
  • For a value type field, copy is done byte-by-byte
  • For a reference type, shallow copy copies the reference but not the referred object

Example:

public class ShallowCopy
{
  public int iValue;
}

public class CloneMe
{
  public ShallowCopy oShallowCopy = new ShallowCopy();

  public CloneMe(int iNewValue)
  {
    oShallowCopy.iValue = iNewValue;
  }

  public object GetCopy()
  {
    return MemberwiseClone();
  }
}

In this case, the shallow copy obtained through GetCopy() will have a field that refers to the same object as the original.

The following code demonstrates using this class:

CloneMe oCloneMeSource = new CloneMe(10);
CloneMe oCloneMeTarget = (CloneMe)oCloneMeSource.GetCopy();
Console.Writeline("oCloneMeTarget - {0}", oCloneMeTarget.oShallowCopy.iValue);  // Output: oCloneMeTarget – 10
oCloneMeSource.oShallowCopy.iValue = 6;
Console.Writeline("oCloneMeTarget - {0}", oCloneMeTarget.oShallowCopy.iValue);  // Output: oCloneMeTarget – 6


Deep Copy


For instances of reference type, the '=' assignment operator copies the reference, and not the object. To copy the state of an object of reference type, we can use deep copying. Deep Copying is achieved by implementing the method Clone() which is the only method in System.ICloneable interface. This method returns a value of type System.Object.

Steps:
  • Create a new object
  • Copy the nonstatic fields of the current object to the new object
  • For a value type field, copy is done byte-by-byte
  • For a reference type, a new copy of the referred object is created

Example:

public class DeepCopy
{
  public int iValue;
}

public class CloneMe : ICloneable
{
  public DeepCopy oDeepCopy = new DeepCopy();

  public CloneMe(int iNewValue)
  {
     oDeepCopy.iValue = iNewValue; 
  }

  public object Clone()
  {
    CloneMe oCloneMe = new CloneMe(oDeepCopy.iValue);
    return oCloneMe;
  }
}

A new CloneMe object using the iValue field of the DeepCopy object contained in the original CloneMe object (oDeepCopy) is created here. This field is a value type, so no deep copying is necessary.

The following code demonstrates using this class:

CloneMe oCloneMeSource = new CloneMe(10);
CloneMe oCloneMeTarget = (CloneMe)oCloneMeSource.Clone();
Console.Writeline("oCloneMeTarget - {0}", oCloneMeTarget.oDeepCopy.iValue);  // Output: oCloneMeTarget – 10
oCloneMeSource.oDeepCopy.iValue = 6;
Console.Writeline("oCloneMeTarget - {0}", oCloneMeTarget.oDeepCopy.iValue);  // Output: oCloneMeTarget – 10

This time, the contained objects are independent.

No comments:

Post a Comment