Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How do you do a deep copy of an object in .NET?
A deep copy in C# creates a completely independent copy of an object, including all its nested objects and reference types. Unlike a shallow copy that only copies references, a deep copy duplicates the entire object hierarchy, ensuring that changes to the copied object do not affect the original.
Deep copying is essential when working with complex objects containing reference types like arrays, lists, or custom objects. Without proper deep copying, modifications to nested objects can unexpectedly affect the original object.
Using Binary Serialization for Deep Copy
One of the most reliable methods for deep copying is using binary serialization. This approach works for any serializable object −
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class Person {
public string Name { get; set; }
public Address HomeAddress { get; set; }
public Person(string name, Address address) {
Name = name;
HomeAddress = address;
}
public Person DeepCopy() {
using (MemoryStream stream = new MemoryStream()) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Position = 0;
return (Person)formatter.Deserialize(stream);
}
}
}
[Serializable]
public class Address {
public string Street { get; set; }
public string City { get; set; }
public Address(string street, string city) {
Street = street;
City = city;
}
}
public class Program {
public static void Main() {
Address originalAddress = new Address("123 Main St", "Springfield");
Person original = new Person("John Doe", originalAddress);
Person deepCopy = original.DeepCopy();
Console.WriteLine("Original: " + original.Name + ", " + original.HomeAddress.Street);
Console.WriteLine("Deep Copy: " + deepCopy.Name + ", " + deepCopy.HomeAddress.Street);
deepCopy.Name = "Jane Doe";
deepCopy.HomeAddress.Street = "456 Oak Ave";
Console.WriteLine("After modification:");
Console.WriteLine("Original: " + original.Name + ", " + original.HomeAddress.Street);
Console.WriteLine("Deep Copy: " + deepCopy.Name + ", " + deepCopy.HomeAddress.Street);
}
}
The output of the above code is −
Original: John Doe, 123 Main St Deep Copy: John Doe, 123 Main St After modification: Original: John Doe, 123 Main St Deep Copy: Jane Doe, 456 Oak Ave
Using JSON Serialization for Deep Copy
A modern approach using JSON serialization with System.Text.Json or Newtonsoft.Json −
using System;
using System.Text.Json;
public class Student {
public string Name { get; set; }
public int[] Grades { get; set; }
public Student(string name, int[] grades) {
Name = name;
Grades = grades;
}
public Student DeepCopy() {
string json = JsonSerializer.Serialize(this);
return JsonSerializer.Deserialize<Student>(json);
}
}
public class Program {
public static void Main() {
Student original = new Student("Alice", new int[] { 90, 85, 92 });
Student copy = original.DeepCopy();
Console.WriteLine("Original grades: " + string.Join(", ", original.Grades));
Console.WriteLine("Copy grades: " + string.Join(", ", copy.Grades));
copy.Grades[0] = 100;
Console.WriteLine("After modifying copy:");
Console.WriteLine("Original grades: " + string.Join(", ", original.Grades));
Console.WriteLine("Copy grades: " + string.Join(", ", copy.Grades));
}
}
The output of the above code is −
Original grades: 90, 85, 92 Copy grades: 90, 85, 92 After modifying copy: Original grades: 90, 85, 92 Copy grades: 100, 85, 92
Manual Deep Copy with ICloneable
For complete control over the copying process, implement the ICloneable interface −
using System;
public class Book : ICloneable {
public string Title { get; set; }
public Author BookAuthor { get; set; }
public Book(string title, Author author) {
Title = title;
BookAuthor = author;
}
public object Clone() {
return new Book(Title, (Author)BookAuthor.Clone());
}
}
public class Author : ICloneable {
public string Name { get; set; }
public Author(string name) {
Name = name;
}
public object Clone() {
return new Author(Name);
}
}
public class Program {
public static void Main() {
Author originalAuthor = new Author("J.K. Rowling");
Book original = new Book("Harry Potter", originalAuthor);
Book copy = (Book)original.Clone();
Console.WriteLine("Original: " + original.Title + " by " + original.BookAuthor.Name);
Console.WriteLine("Copy: " + copy.Title + " by " + copy.BookAuthor.Name);
copy.BookAuthor.Name = "George R.R. Martin";
Console.WriteLine("After modification:");
Console.WriteLine("Original: " + original.Title + " by " + original.BookAuthor.Name);
Console.WriteLine("Copy: " + copy.Title + " by " + copy.BookAuthor.Name);
}
}
The output of the above code is −
Original: Harry Potter by J.K. Rowling Copy: Harry Potter by J.K. Rowling After modification: Original: Harry Potter by J.K. Rowling Copy: Harry Potter by George R.R. Martin
Comparison of Deep Copy Methods
| Method | Advantages | Disadvantages |
|---|---|---|
| Binary Serialization | Automatic, handles complex hierarchies | Requires [Serializable] attribute, .NET Framework only |
| JSON Serialization | Cross-platform, human-readable format | Performance overhead, loses some type information |
| Manual ICloneable | Full control, best performance | Manual implementation required for each class |
Conclusion
Deep copying in .NET ensures complete independence between original and copied objects by duplicating all nested references. Choose serialization methods for automatic copying or implement ICloneable for fine-grained control over the copying process.
