Monday 14 April 2014

What is the Difference between the Deep Clone and Shallow Copy - C#

In this article we are going to see about shallow copy and deep clone, first we have to knew what is cloning getting a new copy of particular object. i.e copy the non-static fields of the object.

             Student std = new Student("Rajesh", 1, 212,12);

Deep Clone :
    In this Deep clone it will create a new copy of that entire object , value types fields have a new copy and reference type field have a new copy by create a new instance.

it is very important that to perform a deep clone class must have a attribute [Serializableand set the memory stream to position 0 otherwise result in some error.


        public Student DeepClone()
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, this);
            ms.Position = 0;
            // if the above line is not there then error will raise as "End of Stream encountered before parsing was completed."
            return (Student)formatter.Deserialize(ms);
        }


              

                Student dc = std.DeepClone();


Shallow Copy :
   In the Shallow Copy it will create a new copy of that entire object using  MemberwiseClone method, Here the value types have a new copy and reference type field have a reference of that previous object instead of create a new instance.


        public Student ShallowCopy()
        {
            return (Student)MemberwiseClone();
               }


                Student shc = std.ShallowCopy();

you can see after get a copy object from shallow copy change the base object reference field value 
base object is std, now change the value of the value type field id and reference type field Depart. You can see the object that this changes can reflect only in the Shallow copy not in the Deep clone.


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace SampleApplication
{
    [Serializable]
    class Student
    {
        public static int Count { set; get; }

        public string Name { set; get; }

        public int Id { set; get; }

        public Department Depart { set; get; }

        public void Process()
        {
            Console.WriteLine("Processing");
        }

        public Student(string name,int id,int departid,int labs)
        {
            Name = name;
            Id = id;
            Depart = new Department(departid,labs);
        }

        public Student ShallowCopy()
        {
            return (Student)MemberwiseClone();
        }

        public Student DeepClone()
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, this);
            ms.Position = 0;
            // if the above line is not there then error will raise as "End of Stream encountered before parsing was completed."
            return (Student)formatter.Deserialize(ms);
        }

    }

    [Serializable]
    class Department
    {
        public int DepartmentId { set; get; }

        public Labs lab { set; get; }

        public Department(int department,int labs)
        {
            DepartmentId = department;
            lab =new Labs(labs);
        }
    }

    [Serializable]
    class Labs
    {
        public int Count;

        public Labs(int count)
        {
            Count = count;
        }
    }
     }

Program :

class Program
        {
            static void Main(string[] args)
            {
                Student std = new Student("Rajesh", 1, 212,12);
               
                Student shc = std.ShallowCopy();
                Student dc = std.DeepClone();
                shc.Process();
                dc.Process();
               
                Console.WriteLine();
                Console.WriteLine(" [Shallow Copy] Department Id " +shc.Depart.DepartmentId);
                Console.WriteLine(" [Deep Clone] Department Id "+dc.Depart.DepartmentId);
                Console.WriteLine(" [Shallow Copy] Department Labs " + shc.Depart.lab.Count);
                Console.WriteLine(" [Deep Clone] Department Labs " + dc.Depart.lab.Count);
               
                Console.WriteLine(" [Shallow Copy] Id "+shc.Id);
                Console.WriteLine(" [Deep Clone] Id "+dc.Id);


                std.Depart.DepartmentId = 4;
                std.Id = 2;
                std.Depart.lab.Count = 15;

                Console.WriteLine("\n Department id is changed from 212 to 4 , id 1 to 2, labs 12 to 15");
                Console.WriteLine();
                Console.WriteLine(" [Shallow Copy] Department Id " + shc.Depart.DepartmentId);
                Console.WriteLine(" [Deep Clone] Department Id " + dc.Depart.DepartmentId);
                Console.WriteLine(" [Shallow Copy] Department Labs " + shc.Depart.lab.Count);
                Console.WriteLine(" [Deep Clone] Department Labs " + dc.Depart.lab.Count);
                Console.WriteLine(" [Shallow Copy] Id " + shc.Id);
                Console.WriteLine(" [Deep Clone] Id " + dc.Id);
               

                Console.Read();
            }     

        }

Output:

Processing
Processing

 [Shallow Copy] Department Id 212
 [Deep Clone] Department Id 212
 [Shallow Copy] Department Labs 12
 [Deep Clone] Department Labs 12
 [Shallow Copy] Id 1
 [Deep Clone] Id 1

 Department id is changed from 212 to 4 , id 1 to 2, labs 12 to 15

 [Shallow Copy] Department Id 4
 [Deep Clone] Department Id 212
 [Shallow Copy] Department Labs 15
 [Deep Clone] Department Labs 12
 [Shallow Copy] Id 1

 [Deep Clone] Id 1



From this article you can learnt the difference and how to use the shallow copy and deep clone.


No comments:

Post a Comment