Object cloning could be tricky — here is all you need to know
Paying attention to whether the cloned or copied objects work as intended is relevant, aka the difference between shallow and deep copy.
What is the difference between shallow and deep copy?
Deep-copy copies the cloned object and all objects referenced by the object, recursively until all objects in the object are copied. A shallow copy may do none, or part of a real deep clone.
It depends on the situation and what kind of clone should you use in your project. In the following, we will see some examples in C# regarding the discussed topic.
How to create shallow and deep copies
For this, I created a .NET console application.
You can find the source code here.
Program setup
Person.cs
- The blueprint for the object we will clone later.
Address.cs
- Data for the Person
class.
Program.cs
- Where the cloning will take place, contains Main
, the entry point of the application.
After creating the classes, overriding the inherited ToString()
function and running the program the output:
As we can see the person object is allocated in the memory correctly.
Create a shallow clone
To create a shallow clone we could just simply add the following lines to the Main
method:
or implement the Clone()
method in Person
and add the following lines to the Main
method:
The result will be the same using the two methods:
As you can see the person and the shallowClone object points to the same memory address. It means if the shallowClone changes the person will change too.
Create a deep clone
To create a deep clone we need to change the Clone()
method in Person
and add the following lines to the Main
method:
The output after running again:
As we can see the new deepClone object points to a different memory address but the Address attribute of the three objects still has the same address in the memory.
That means if the FirstName, LastName or Age is changed in the deepClone object that does not affect the other two objects. But if we change the Address in deepClone that will affect the original person and shallowClone object too.
To solve this problem we need to change the Address
class to implement ICloneable
too, then add a Clone()
method
and change Clone()
method in Person
.
The output after fixing:
As we can see the deepClone has its own address in memory and the problem with the Address attribute is solved. That means if the fields are changed (even the Address) it won’t affect the original object. It’s an independent object from the original with the same values, so we were able to create a real deep clone of the original object.
Conclusion
Understanding the differences between shallow and deep clones and copies is important to make the program behave the way we expect it to. As you can see from the example above, it is difficult to create a perfect deep copy in .NET with the ICloneable interface if you have a complex hierarchy of classes and objects (here it wasn’t the case but in a bigger model it would be problematic). I have written about the issues concerning ICloneable
in another article here.
Hi, guys, I’m Roland and I’m here to share with all of you my passion for development, computer engineering, project management, personal development, hobbies, and everything in between.
Feel free to contact me anytime — I would love to exchange new ideas and inspire each other!