Learn how deep copy and shallow copy can be used to create a clone of an object in .Net Microsoft .Net provides support for cloning objects — an ability to create an exact copy of an object (also known as a clone). Cloning can be of two types: shallow copy and deep copy. While the former can be implemented by making a call to the MemberwiseClone method of the System.Object class, implementing the latter is a bit tricky as you don’t have support for it in the framework by default. In essence, while a shallow copy copies the references sans the referenced objects, a deep clone creates a copy of the source object together with its references. What are all the available options for cloning? To clone an instance of a class in C#, you have a few options to choose from. These include the following: Using the System.Object.MemberwiseClone method to perform a shallow copy Using Reflection by taking advantage of the Activator.CreateInstance method Using Serialization By implementing the IClonable interface Note that when cloning objects or instances of classes in .Net, you need not consider static members or static fields. The reason is that static objects are stored in a shared memory location and you have one memory location allocated for them per application domain. Shallow copy vs. deep copy Consider a class Employee and that we create an instance of the Employee class as shown below. Employee emp = new Employee(); Employee clone = emp; Refer to the code snippet above. The assignment operator “=” would copy the reference and not the actual object. The MemberwiseClone() method defined in the System.Object class does exactly the same thing. These are examples of shallow copy. Hence when you use an assignment operator to copy and object to another or, use the Memberwise.Clone() method, you are actually doing a shallow copy of the object. While in shallow copy the members of the copied object refer to the same object as the original object, in a deep copy, separate instances of each of the reference type members in the original instance is created in the new or cloned instance. Hence if you have a reference type in the original instance, the new instance will also contain the same reference type member in it but this reference type will point to an altogether new instance. In shallow copy, a new object is created and then the non-static members of the source object is copied to the target object or the new object. If the member is a value type field then a bit by bit copy of the field is performed. In contrast, if the member being copied is a reference type, the reference is copied. Hence, the reference member inside the original object and the target objects refer to the same object in the memory. If you have a collection with individual elements inside and you would want to perform a shallow copy the collection instance. It should be noted that a shallow copy of a collection instance copies the structure of the collection but not the elements inside the collection. Hence, after you perform a shallow copy of the collection instance, you would have two collections sharing the individual elements of the collection. On the contrary, if you perform a deep copy of the collection instance, you would have two collection instances with the individual elements of the original collection duplicated. Implementing deep copy using serialization You can implement deep copy in many ways. One of the most preferred ways to implement a deep copy of an object is by using serialization. You can also leverage reflection to perform a deep copy of an instance of a class. The following code snippet illustrates how you can write a method that implements binary serialization to perform a deep copy of an instance using C#. public static T DeepCopy<T>(T obj) { if (!typeof(T).IsSerializable) { throw new Exception("The source object must be serializable"); } if (Object.ReferenceEquals(obj, null)) { throw new Exception("The source object must not be null"); } T result = default(T); using (var memoryStream = new MemoryStream()) { var formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, obj); memoryStream.Seek(0, SeekOrigin.Begin); result = (T)formatter.Deserialize(memoryStream); memoryStream.Close(); } return result; } Considering that you have an entity class called Employee, you can perform a deep copy of an instance of the Employee class as shown in the code snippet below. static void Main(string[] args) { Employee emp = new Employee(); emp.EmployeeId = 1; emp.FirstName = "Joydip"; emp.LastName = "Kanjilal"; Employee clone = DeepCopy<Employee>(emp); if(Object.ReferenceEquals(emp, clone)) { Console.WriteLine("References are the same."); } else { Console.WriteLine("References are different."); } } When you execute the above program, a deep copy of the instance “emp” would be performed and the message “References are different.” will be displayed. Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos