Как создают новую глубокую копию (клон) Списка <T>?

В следующей части кода,

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;
        }
    }

}

Я использую a Book тип объекта для создания a List<T> и я заполняю его с несколькими объектами, дающими им уникальный заголовок (от 'одного' до 'пять').

Затем я создаю List<Book> books_2 = new List<Book>(books_1).

От этой точки я знаю, что это - клон объекта списка, НО книжные объекты от book_2 все еще ссылка от книжных объектов в books_1. Это доказано путем внесения изменений на двух первых элементах books_2, и затем проверяя те те же элементы book_1 в a TextBox.

books_1[0].title and books_2[1].title были действительно изменены на новые значения books_2[0].title and books_2[1].title.

ТЕПЕРЬ ВОПРОС

Как мы создаем новую твердую копию a List<T>? Идея - это books_1 и books_2 станьте абсолютно независимыми друг от друга.

Я разочарован, Microsoft не предложила аккуратного, быстрого и легкого решения как Ruby, делают с clone() метод.

То, что было бы действительно потрясающим от помощников, должно использовать мой код и изменить его с осуществимым решением, таким образом, он может быть скомпилирован и работать. Я думаю, что это действительно поможет новичкам, пытающимся понять предлагаемые решения для этой проблемы.

Править: Обратите внимание что Book класс мог быть более сложным и иметь больше свойств. Я пытался сохранить вещи простыми.

59
задан 23 December 2012 в 03:32

2 ответа

public static class Cloner
{
    public static T Clone<T>(this T item)
    {
        FieldInfo[] fis = item.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
        object tempMyClass = Activator.CreateInstance(item.GetType());
        foreach (FieldInfo fi in fis)
        {
            if (fi.FieldType.Namespace != item.GetType().Namespace)
                fi.SetValue(tempMyClass, fi.GetValue(item));
            else
            {
                object obj = fi.GetValue(item);
                if (obj != null)
                    fi.SetValue(tempMyClass, obj.Clone());
            }
        }
        return (T)tempMyClass;
    }
}
1
ответ дан 1 November 2019 в 11:19

Можно использовать это:

var newList= JsonConvert.DeserializeObject<List<Book>>(list.toJson());
1
ответ дан 1 November 2019 в 11:19

Другие вопросы по тегам:

Похожие вопросы: