In the following piece of code,
using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace clone_test_01 { public partial class MainForm : Form { public class Book { public string title = ""; public Book(string title) { this.title = title; } } public MainForm() { InitializeComponent(); List<Book> books_1 = new List<Book>(); books_1.Add( new Book("One") ); books_1.Add( new Book("Two") ); books_1.Add( new Book("Three") ); books_1.Add( new Book("Four") ); List<Book> books_2 = new List<Book>(books_1); books_2[0].title = "Five"; books_2[1].title = "Six"; textBox1.Text = books_1[0].title; textBox2.Text = books_1[1].title; } } }
I use a Book
object type to create a List<T>
and I populate it with a few items giving them a unique title (from 'one' to 'five').
Then I create List<Book> books_2 = new List<Book>(books_1)
.
From this point, I know it's a clone of the list object, BUT the book objects from book_2
are still a reference from the book objects in books_1
. It's proven by making changes on the two first elements of books_2
, and then checking those same elements of book_1
in a TextBox
.
books_1[0].title and books_2[1].title
have indeed been changed to the new values of books_2[0].title and books_2[1].title
.
NOW THE QUESTION
How do we create a new hard copy of a List<T>
? The idea is that books_1
and books_2
become completely independent of each other.
I'm disappointed Microsoft didn't offer a neat, fast and easy solution like Ruby are doing with the clone()
method.
What would be really awesome from helpers is to use my code and alter it with a workable solution so it can be compiled and work. I think it will truly help newbies trying to understand offered solutions for this issue.
EDIT: Note that the Book
class could be more complex and have more properties. I tried to keep things simple.
Copy an Object With Object.assign() was the most popular way to deep copy an object. Object. assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn't affect the original object.
clone() is indeed a shallow copy. However, it's designed to throw a CloneNotSupportedException unless your object implements Cloneable . And when you implement Cloneable , you should override clone() to make it do a deep copy, by calling clone() on all fields that are themselves cloneable.
You need to create new Book
objects then put those in a new List
:
List<Book> books_2 = books_1.Select(book => new Book(book.title)).ToList();
Update: Slightly simpler... List<T>
has a method called ConvertAll
that returns a new list:
List<Book> books_2 = books_1.ConvertAll(book => new Book(book.title));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With