Create a deep copy of a List in C#
This post will discuss how to create a deep copy of a List in C#.
1. Using Constructor
You can use a constructor to create a copy of objects in C#. To create a deep copy of a list of objects, you can iterate through the list and create a copy of each item by invoking its constructor. This approach is can be used if the class is not complex and contains few properties. A typical implementation of this approach would look like below using the Select() or ConvertAll() method:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; using System.Linq; using System.Collections.Generic; class Student { public string name { get; set; } public decimal age { get; set; } public override string ToString() { return "[" + name + ", " + age + "]"; } } public class Example { public static void Main() { var list = new List<Student> { new Student{name = "Olivia", age = 10}, new Student{name = "Robert", age = 20}, new Student{name = "John", age = 15} }; // Using Select() var copy1 = list.Select(s => new Student{name = s.name, age = s.age}).ToList(); Console.WriteLine(String.Join(", ", copy1)); // Using ConvertAll() var copy2 = list.ConvertAll(s => new Student{name = s.name, age = s.age}).ToList(); Console.WriteLine(String.Join(", ", copy2)); } } |
Output:
[Olivia, 10], [Robert, 20], [John, 15]
[Olivia, 10], [Robert, 20], [John, 15]
C# had made it possible to write simpler and concise code. Starting with C#9, you can take advantage of the new with expression if your object contains many fields. The with expression can create a copy of any record with an arbitrary number of its init-only properties modified. The following code example demonstrates its usage:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
using System; using System.Linq; using System.Collections.Generic; class Student { public string name { get; set; } public decimal age { get; set; } public override string ToString() { return "[" + name + ", " + age + "]"; } } public class Example { public static void Main() { var list = new List<Student> { new Student{name = "Olivia", age = 10}, new Student{name = "Robert", age = 20}, new Student{name = "John", age = 15} }; var copy = list.Select(s => s with { }).ToList(); Console.WriteLine(String.Join(", ", copy)); } } |
Output:
[Olivia, 10], [Robert, 20], [John, 15]
2. Using Clone() method
Alternatively, you can implement your own Clone() method to facilitate a field-for-field copy of a class. Then you can simply loop over the list and clone each item by invoking the Clone() method, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using System; using System.Linq; using System.Collections.Generic; class Student { public string name { get; set; } public decimal age { get; set; } public Student Clone() { return new Student {name = this.name, age = this.age}; } public override string ToString() { return "[" + name + ", " + age + "]"; } } public class Example { public static void Main() { var list = new List<Student> { new Student{name = "Olivia", age = 10}, new Student{name = "Robert", age = 20}, new Student{name = "John", age = 15} }; var copy = list.ConvertAll(s => s.Clone()).ToList(); Console.WriteLine(String.Join(", ", copy)); } } |
Output:
[Olivia, 10], [Robert, 20], [John, 15]
3. Using Serializable() Method
Finally, you can use serialization to serialize an object into a MemoryStream and then deserialize it back. To indicate that instances of a class can be serialized, apply the SerializableAttribute attribute. The following example demonstrates the serialization of a List of objects.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System; using System.IO; using System.Collections.Generic; using System.Runtime.Serialization.Formatters.Binary; [Serializable()] class Student { public string name { get; set; } public decimal age { get; set; } public override string ToString() { return "[" + name + ", " + age + "]"; } } public static class Extensions { public static List<T> Clone<T>(this List<T> list) { BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, list); stream.Position = 0; return (List<T>) formatter.Deserialize(stream); } } public class Example { public static void Main() { var list = new List<Student> { new Student{name = "Olivia", age = 10}, new Student{name = "Robert", age = 20}, new Student{name = "John", age = 15} }; var copy = list.Clone(); Console.WriteLine(String.Join(", ", copy)); } } |
Output:
[Olivia, 10], [Robert, 20], [John, 15]
That’s all about creating a deep copy of a List in C#.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)