Monday, 2 January 2023

Shallow Copy and Deep Copy in C#

 In general, when we try to copy one object to another object, both the objects will share the same memory address. Normally, we use assignment operator, = , to copy the reference, not the object except when there is value type field. This operator will always copy the reference, not the actual object. For Example: Suppose G1 refers to memory address 5000 then G2 will also refer to 5000. So if one will change the value of data stored at address 5000 then both G1 and G2 will show the same data.

Geeks G1 = new Geeks();

// Copy the instance using 
// '=' operator
Geeks G2 = G1;

Shallow Copy: Creating a new object and then copying the value type fields of the current object to the new object. But when the data is reference type, then the only reference is copied but not the referred object itself. Therefore the original and clone refer to the same object. The concept will more clear when you will see the code and the diagram of the Shallow copy.

Note: In the above diagram The Global Rank is value type field so it creates the copy of that and store it in different location but the Name (Desc) is Reference type field so it’s pointing to the old or main memory location.

Example: Here, if you will change value type then it is working on c2 and c1, and not affected but in reference type any change will affect both c1 and c2.

// C# program to illustrate the 
// concept of Shallow Copy
using System;
      
class Example {
      
// Main Method
static void Main(string[] args)
{
      
    Company c1 = new Company(548, "GeeksforGeeks",
                                  "Sandeep Jain");
      
    // Performing Shallow copy                      
    Company c2 = (Company)c1.Shallowcopy(); 
  
    Console.WriteLine("Before Changing: ");
      
    // Before changing the value of
    // c2 GBRank and CompanyName
    Console.WriteLine(c1.GBRank);
    Console.WriteLine(c2.GBRank);
    Console.WriteLine(c2.desc.CompanyName);
    Console.WriteLine(c1.desc.CompanyName);
  
    // changing the value of c2 GBRank
    // and CompanyName
    c2.GBRank = 59;
    c2.desc.CompanyName = "GFG";
  
    Console.WriteLine("\nAfter Changing: ");
      
    // After changing the value of 
    // c2 GBRank and CompanyName
    Console.WriteLine(c1.GBRank);
    Console.WriteLine(c2.GBRank);
    Console.WriteLine(c2.desc.CompanyName);
    Console.WriteLine(c1.desc.CompanyName);
}
}
  
  
class Company 
{
          
    public int GBRank;
    public CompanyDescription desc;
      
    public Company(int gbRank, string c,
                               string o)
    {
        this.GBRank = gbRank;
        desc = new CompanyDescription(c, o);
    }
      
    // method for cloning object
    public object Shallowcopy()
    {
        return this.MemberwiseClone();
    }
      
    // method for cloning object
    public Company DeepCopy()
    {
        Company deepcopyCompany = new Company(this.GBRank,
                            desc.CompanyName, desc.Owner);
        return deepcopyCompany;
    }
}
      
      
class CompanyDescription 
{
      
    public string CompanyName;
    public string Owner;
    public CompanyDescription(string c, string o)
    {
        this.CompanyName = c;
        this.Owner = o;
    }
}
Output:
Before Changing: 
548
548
GeeksforGeeks
GeeksforGeeks

After Changing: 
548
59
GFG
GFG

Deep Copy: It is a process of creating a new object and then copying the fields of the current object to the newly created object to make a complete copy of the internal reference types. If the specified field is a value type, then a bit-by-bit copy of the field will be performed. If the specified field is a reference type, then a new copy of the referred object is performed.

Note:In the above diagram The Global Rank is value type field so it creates the copy of that and store it in different location. The Name(Desc) is Reference type field so in Deep Copy there is a clone of reference type field which also will be stored in a different location.

Example: Here, the field type does not matter whether it is value type or reference type. Deep copy makes a copy of whole data and store it in a different memory location so if we change c2, c1 will not affected vice versa also.

// C# program to demonstrate the
// concept of Deep copy
using System;
  
namespace ShallowVSDeepCopy {
      
class Program {
      
    // Main Method
    static void Main(string[] args)
    {
        Company c1 = new Company(548, "GeeksforGeeks",
                                      "Sandeep Jain");
        // Performing Deep copy                             
        Company c2 = (Company)c1.DeepCopy(); 
  
        Console.WriteLine("Before Changing: ");
           
        // Before changing the value of 
        // c2 GBRank and CompanyName
        Console.WriteLine(c1.GBRank);
        Console.WriteLine(c2.GBRank);
        Console.WriteLine(c2.desc.CompanyName);
        Console.WriteLine(c1.desc.CompanyName);
  
        Console.WriteLine("\nAfter Changing: ");
          
        // changing the value of c2 
        // GBRank and CompanyName
        c2.GBRank = 59;
        c2.desc.CompanyName = "GFG";
  
        // After changing the value of
        // c2 GBRank and CompanyName
        Console.WriteLine(c1.GBRank);
        Console.WriteLine(c2.GBRank);
        Console.WriteLine(c2.desc.CompanyName);
        Console.WriteLine(c1.desc.CompanyName);
    }
}
  
class Company {
      
    public int GBRank;
    public CompanyDescription desc;
  
    public Company(int gbRank, string c, 
                               string o)
    {
        this.GBRank = gbRank;
        desc = new CompanyDescription(c, o);
    }
      
    // method for cloning object
    public object Shallowcopy()
    {
        return this.MemberwiseClone();
    }
      
    // method for cloning object
    public Company DeepCopy()
    {
        Company deepcopyCompany = new Company(this.GBRank,
                           desc.CompanyName, desc.Owner);
                             
        return deepcopyCompany;
    }
}
  
class CompanyDescription {
      
    public string CompanyName;
    public string Owner;
    public CompanyDescription(string c, 
                             string o)
    {
        this.CompanyName = c;
        this.Owner = o;
    }
}
}
Output:
Before Changing: 
548
548
GeeksforGeeks
GeeksforGeeks

After Changing: 
548
59
GFG
GeeksforGeeks

No comments:

Post a Comment