Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How create a new deep copy (clone) of a List<T>?

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.

like image 860
TheScholar Avatar asked Dec 22 '12 23:12

TheScholar


People also ask

How do you create a deep clone of an object?

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.

Does clone () make a deep copy?

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.


1 Answers

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)); 
like image 149
Mark Byers Avatar answered Oct 13 '22 04:10

Mark Byers