Shallow copying is creating a new object and then copying the non-static fields of the current object to the new object. If a field is a value type, then bit-by-bit copy of the field is performed. For a reference type, the reference is copied but the referred object is not; therefore the original object and its clone refer to the same object.
What it means is that instead of creating new objects, shallow copy scenario shares a single reference. So, changing value via one reference will impact the value represented by the other reference.
MemberwiseClone
This object creates shallow copy by creating a new object.
Shallow copy code and explanation –
- public class Human
- {
- public int Age;
- public string Name;
- public IdInfo IdInfo;
-
- public Human ShallowCopy() {
- return (Human)this.MemberwiseClone();
- }
- }
- public class Example
- {
- public static void Main()
- {
- Human p1 = new Human();
- p1.Age = 20;
- p1.Name = "t1";
- p1.IdInfo = new IdInfo(100);
- Human p2 = p1.ShallowCopy();
-
- Console.WriteLine("Original values of p1 and p2:");
- Console.WriteLine(" p1 instance values: ");
- DisplayValues(p1);
- Console.WriteLine(" p2 instance values:");
- DisplayValues(p2);
- p1.Age = 30;
- p1.Name = "t2";
- p1.IdInfo.IdNumber = 200;
- Console.WriteLine("\nValues of p1 and p2 after changes to p1:");
- Console.WriteLine(" p1 instance values: ");
- DisplayValues(p1);
- Console.WriteLine(" p2 instance values:");
- DisplayValues(p2);
- Console.ReadLine();
- }
- public static void DisplayValues(Human p)
- {
- Console.WriteLine(" Name: {0:s}, Age: {1:d}", p.Name, p.Age);
- Console.WriteLine(" Value: {0:d}", p.IdInfo.IdNumber);
- }
- }
Explanation
Deep Copy
Deep copies duplicate everything. Two different objects get created with shared reference. It means, in deep copy, object is copied along with the objects to which it refers.
There are multiple ways to perform "Deep Copy".
Some are discussed below.
- Use copy constructor and create new object.
- You can call MemberwiseClone method and create a shallow copy of an object, and then assign new objects whose values are reference types.
- You can serialize object and then de-Serialize the object to different object variable.
- You can do serialization of data and then deserialize the data to new object.
- Use reflection with recursion.
Code and explanation
- using System;
-
- public class IdInfo
- {
- public int IdNumber;
-
- public IdInfo(int IdNumber)
- {
- this.IdNumber = IdNumber;
- }
- }
-
- public class Human
- {
- public int Age;
- public string Name;
- public IdInfo IdInfo;
-
- public Human DeepCopy()
- {
- Human other = (Human)this.MemberwiseClone();
- other.IdInfo = new IdInfo(IdInfo.IdNumber);
- other.Name = String.Copy(Name);
- return other;
- }
- }
-
- public class Example
- {
- public static void Main()
- {
- Human p1 = new Human();
- p1.Age = 20;
- p1.Name = "t1";
- p1.IdInfo = new IdInfo(100);
- Human p3 = p1.DeepCopy();
- p1.Name = "t2";
- p1.Age = 30;
- p1.IdInfo.IdNumber = 200;
- Console.WriteLine("\nValues of p1 and p3 after changes to p1:");
- Console.WriteLine(" p1 instance values: ");
- DisplayValues(p1);
- Console.WriteLine(" p3 instance values:");
- DisplayValues(p3);
- Console.ReadLine();
- }
-
- public static void DisplayValues(Human p)
- {
- Console.WriteLine(" Name: {0:s}, Age: {1:d}", p.Name, p.Age);
- Console.WriteLine(" Value: {0:d}", p.IdInfo.IdNumber);
- }
- }
Explanation An Explanatory example of both (taken from StackOverflow) - class A
- {
- public int a = 0;
- public void display()
- {
- Console.WriteLine("The value of a is " + a);
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- A ob1 = new A();
- ob1.a = 10;
- ob1.display();
- A ob2 = new A();
- ob2 = ob1;
- ob2.display();
- Console.Read();
- }
- }
Question-Which type of copy is this?
Answer-Shallow Copy
- ob1.a = 5;
-
- Deep Copy will be:
- A ob1 = new A();
- ob1.a = 10;
- A ob2 = new A();
- ob2.a = ob1.a;
-
- ob1.a = 5;
Shocking-This does not go with my diagram. Here, we equate the objects using “=” sign.
Note- Read “=” in terms of objects. Just to give heads up, using “=” ,share the reference.
Additional Notes
ICloneable interface is the key to learn object cloning.
Memberwise also uses this interface internally to do shallow copy and this same interface can be used to perform deep copy. I thought to explain but they are already explained in best possible way at the below links.
Recommended Reading,
- http://www.informit.com/articles/article.aspx?p=25352&seqNum=3
- http://www.windowsdevcenter.com/pub/a/dotnet/2002/11/25/copying.html?page=2
- http://stackoverflow.com/questions/3345389/copy-constructor-versus-clone
- http://seesharpconcepts.blogspot.com/2012/05/shallow-copy-and-deep-copy-in-c.html
- http://www.cshandler.com/2012/07/shallow-copy-and-deep-copy-using.html#.Vdwms9zVFJs
- https://www.agiledeveloper.com/articles/cloning072002.htm