Click here to Skip to main content
Click here to Skip to main content

Shallow Copy vs. Deep Copy in .NET

By , 10 Oct 2008
 

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.

// Creates an instance of clsShallow and assign values to its fields.
clsShallow objshallow = new clsShallow();
objshallow.Age = 25;
objshallow.EmployeeName = "Ahmed Eid";

// add the ref value to the objshallow 
clsRefSalary clsref = new clsRefSalary(1000);
objshallow.EmpSalary = clsref;

// Performs a shallow copy of m1 and assign it to m2.
clsShallow m2 = objshallow.CreateShallowCopy(objshallow);

// then modify the clsref salary value to be 2000
clsref.Salary = 2000;

// so the m1 object salary value become 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).

shal1

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.

shal1

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]
// serialize the classes in case of deep copy
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.

// Creates an instance of clsDeep and assign values to its fields.
clsDeep objdeep = new clsDeep();
objdeep.Age = 25;
objdeep.EmployeeName = "Ahmed Eid";

// add the ref value
clsRefSalary clsref = new clsRefSalary(1000);
objdeep.EmpSalary = clsref;

// Performs a shallow copy of m1 and assign it to m2.
clsDeep m2 = objdeep.CreateDeepCopy(objdeep);

// then modify the clsref salary value to be 2000 
clsref.Salary = 2000;

// so the m1 object salary value become 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).

deep1

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.

deep1

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.

/// <summary>
/// Using generics will solve some performance issues
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="item"></param>
/// <returns></returns>
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ahmad Eid Salim
Software Developer (Senior)
Egypt Egypt
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberMember 829355710 Feb '13 - 18:39 
I understood the concept
GeneralMy vote of 4memberAwchie3 Jan '13 - 16:26 
Great Explanation. But you could have made it simpler.
QuestionThanksmemberAshish payghan24 Dec '12 - 0:46 
I understand concept, Good article. Thanks Ahmad for posting this article.
GeneralMy vote of 3memberchandusonkarkwh15 Apr '12 - 2:50 
good example
QuestionQuestionmemberMember 43531606 Oct '11 - 3:05 
Do we have to write our own method to perform deep copy?
GeneralVery Good ArticlememberImtiaz.Ahmed22 Apr '11 - 9:24 
Good explanation. I understand deep copy Shallow copy after reading this article.
GeneralMy vote of 3memberSonisachin27 Jun '10 - 20:33 
Contents are good.....
GeneralGood article, but given less attention in sample code attachedmemberMember 258204413 May '10 - 20:06 
sorry if i get rude but i found you an MCP (master of copy paste)! output of your sample code is same for shallow and deep copy as you have used wrong object while showing the value also comments are same for both shallow and deep.
 
Anyways thanks for the article, helped in understanding the core difference.
 
D
GeneralIt is an awesome explanation...Keep posting such a practical and easy to understand conceptsmemberMember 32159018 May '10 - 6:03 
It is an awesome explanation...Keep posting such a practical and easy to understand concepts
GeneralThank you very muchmembern_zaheer_ahmed22 Mar '10 - 4:45 
Thank you very much .May Allah guide u .

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 11 Oct 2008
Article Copyright 2008 by Ahmad Eid Salim
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid