How to Deep Clone / Copy Objects in C#

Post author: Adam VanBuskirk
Adam VanBuskirk
5/13/23 in
Tech
C#

You can deep clone or copy objects in C# so that changes made to the new object do not affect the original object. In this post, we’ll show you a handful of ways to do this.

Using Serialization and Deserialization

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class Person {
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program {
    static void Main(string[] args) {
        Person original = new Person { Name = "John", Age = 30 };
        
        // Create a new stream to serialize the object
        MemoryStream stream = new MemoryStream();

        // Create a BinaryFormatter object to serialize the object to the stream
        BinaryFormatter formatter = new BinaryFormatter();

        // Serialize the object to the stream
        formatter.Serialize(stream, original);

        // Reset the stream position to the beginning
        stream.Position = 0;

        // Deserialize the object from the stream
        Person clone = (Person)formatter.Deserialize(stream);

        // Change the name of the cloned object
        clone.Name = "Jane";

        // The original object remains unchanged
        Console.WriteLine("Original: Name={0}, Age={1}", original.Name, original.Age);
        Console.WriteLine("Clone: Name={0}, Age={1}", clone.Name, clone.Age);
    }
}

In this example, we have a Person class with Name and Age properties. We create an instance of this class and set its Name and Age properties to “John” and 30, respectively.

We then create a new MemoryStream object and a BinaryFormatter object to serialize the Person object to the stream. After serializing the object, we reset the stream position to the beginning and deserialize the object to create a clone of the original object.

We then change the Name property of the cloned object to “Jane”, while leaving the original object unchanged. Finally, we print out the Name and Age properties of both objects to show that the original object remains unchanged.

Note that in order for this deep cloning process to work, the class being cloned must be marked as [Serializable]. Additionally, any classes that are referenced by the class being cloned must also be marked as [Serializable].

Using a Copy Constructor

You can create a copy constructor for your class that takes an instance of the same class and copies the values of all properties and fields from the source object to the new object. Here’s an example:

public class Person {
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(Person other) {
        this.Name = other.Name;
        this.Age = other.Age;
    }
}

To create a deep copy of a Person object using the copy constructor, you can simply pass the original object as a parameter:

Person original = new Person { Name = "John", Age = 30 };
Person clone = new Person(original);

Using a serialization surrogate

Instead of using the default serialization process, you can implement a custom serialization surrogate that creates a deep copy of the object. Here’s an example:

using System.Runtime.Serialization;

public class Person {
    public string Name { get; set; }
    public int Age { get; set; }
}

public class PersonSurrogate : ISerializationSurrogate {
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
        Person person = (Person)obj;
        info.AddValue("Name", person.Name);
        info.AddValue("Age", person.Age);
    }

    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {
        Person person = (Person)obj;
        person.Name = info.GetString("Name");
        person.Age = info.GetInt32("Age");
        return person;
    }
}

To use the surrogate, you need to create a new BinaryFormatter object and set its SurrogateSelector property to an instance of a SurrogateSelector object that has registered the PersonSurrogate object as a surrogate for the Person class:

Person original = new Person { Name = "John", Age = 30 };

BinaryFormatter formatter = new BinaryFormatter();
SurrogateSelector selector = new SurrogateSelector();
selector.AddSurrogate(typeof(Person), new StreamingContext(StreamingContextStates.All), new PersonSurrogate());
formatter.SurrogateSelector = selector;

MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, original);
stream.Position = 0;
Person clone = (Person)formatter.Deserialize(stream);

These are just a few examples of how you can deep clone objects in C#. The best approach depends on the specific requirements of your application.

Sign up today for our weekly newsletter about AI, SEO, and Entrepreneurship

Leave a Reply

Your email address will not be published. Required fields are marked *


Read Next




© 2024 Menyu LLC