В следующей части кода,
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
класс мог быть более сложным и иметь больше свойств. Я пытался сохранить вещи простыми.
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;
}
}
Можно использовать это:
var newList= JsonConvert.DeserializeObject<List<Book>>(list.toJson());