Introduction
This article describes the difference between shallow and deep copy using C#. Shallow and deep copy are used for copying data between objects.
Shallow Copy
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 --> a 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.
In C# and VB.NET, shallow copy is done by the object method MemberwiseClone()
.
Example: the following clsShallow
class is to be cloned which includes value types (like Age
) and ref types (like EmpSalary
is a class):
public class clsShallow
{
public static string CompanyName = "My Company";
public int Age;
public string EmployeeName;
public clsRefSalary EmpSalary;
public clsShallow CreateShallowCopy(clsShallow inputcls)
{
return (clsShallow)inputcls.MemberwiseClone();
}
}
public class clsRefSalary
{
public clsRefSalary(int _salary)
{
Salary = _salary;
}
public int Salary;
}
Now let us debug and trace the outputs to do shallow copy using the CreateShallowCopy()
method.
First, use the following code to call the CreateShallowCopy
method from other classes.
clsShallow objshallow = new clsShallow();
objshallow.Age = 25;
objshallow.EmployeeName = "Ahmed Eid";
clsRefSalary clsref = new clsRefSalary(1000);
objshallow.EmpSalary = clsref;
clsShallow m2 = objshallow.CreateShallowCopy(objshallow);
clsref.Salary = 2000;
int EmpSalary = objshallow.EmpSalary.Salary;
After assigning the values (value and ref types) to the object objShallow
and before doing the shallow copy,
the values are (for the current object value): Age
: 25 (value type), EmpSalry
: has salary value of 1000 (ref type).
then do the shallow copy and modify the value of clsref.salary
, reference field type, then check the value of m2,
the newly created object (ref and value fields) again.
The values are (for the newly created object): Age
: 25 (value type), a new copy of the objShallow
object; EmpSalry
: has a salary value of 2000 (ref type),
a reference to objShallow.EmpSalry
object, which is also referenced to the clsref
object.
Note: values of m2.EmpSalry
and clsref
are the same after modifying the clsref
values (reference type concept).
Deep Copy
Deep copy is creating a new object and then copying the nonstatic fields of the current object to the new object. If a field is a value type --> a bit-by-bit copy of the field is performed.
If a field is a reference type --> a new copy of the referred object is performed.
Note: the classes to be cloned must be flagged as [Serializable]
.
Example: the following is the clsDeep
class to be cloned which includes value types (like Age
) and ref types (like EmpSalary
which is a class).
[Serializable]
public class clsDeep
{
public static string CompanyName = "My Company";
public int Age;
public string EmployeeName;
public clsRefSalary EmpSalary;
public clsDeep CreateDeepCopy(clsDeep inputcls)
{
MemoryStream m = new MemoryStream();
BinaryFormatter b = new BinaryFormatter();
b.Serialize(m, inputcls);
m.Position = 0;
return (clsDeep)b.Deserialize(m);
}
}
[Serializable]
public class clsRefSalary
{
public clsRefSalary(int _salary)
{
Salary = _salary;
}
public int Salary;
}
Now let us debug and trace the outputs to do deep copy using the CreateDeepCopy()
method.
First, use the following code to call the CreateDeepCopy
method from other classes.
clsDeep objdeep = new clsDeep();
objdeep.Age = 25;
objdeep.EmployeeName = "Ahmed Eid";
clsRefSalary clsref = new clsRefSalary(1000);
objdeep.EmpSalary = clsref;
clsDeep m2 = objdeep.CreateDeepCopy(objdeep);
clsref.Salary = 2000;
int EmpSalary = objdeep.EmpSalary.Salary;
After assigning the values (value and ref types) to the object objDeep
and before doing the deep copy, the values are (for the current
object value): Age
: 25 (value type); EmpSalry
: has salary value of 1000 (ref type).
Then do a deep copy and modify the value of clsref.salary
, reference field type, then check the value of m2
, the newly created object (ref and value fields) again.
The values are (for the newly created object): Age
: 25 (value type), a new copy of the objDeep
object; EmpSalry
: has a salary value of 1000,
a new copy of the objDeep
object.
Note: values of m2.EmpSalry
and objDeep.EmpSalary
are not the same as deep copy creates a new object of the reference type (objDeep.EmpSalary
)
in m2.EmpSalry
. But clsref
and objDeep.EmpSalary
are the same (reference type concept).
With the help of Google, I found a very smart method for performing deep copy. Its performance is good than that of the one I used above.
public static T DeepCopy<T>(T item)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, item);
stream.Seek(0, SeekOrigin.Begin);
T result = (T)formatter.Deserialize(stream);
stream.Close();
return result;
}
You can find that article at: http://ahmadeed.blogspot.com.
I hope this article helps you to deeply understand the difference between shallow and deep copy in .NET.