Создание полной копии (deep copy) объекта - C#

Узнай цену своей работы

Формулировка задачи:

Всем привет, понадобилось в проекте создать полную копию объекта, для чего воспользовался двоичной сериализацией:
    public static class ExtensionMethods
    {
        public static T DeepClone<T>(this T obj)
        {
            using (var ms = new MemoryStream())
            {
                var formatter = new BinaryFormatter();
                formatter.Serialize(ms, obj);
                ms.Position = 0;
 
                return (T)formatter.Deserialize(ms);
            }
        }
    }
Все хорошо, но почему-то после этого ссылки на объект потерялись. Чтобы было понятнее, подготовил простой тестовый проект, где можно воспроизвести проблему.
    [Serializable]
    public class DateAndTime
    {
        public bool Date { get; set; }
        public bool Time { get; set; }
    }
    public partial class MainForm : Form
    {
        private DateAndTime obj;
 
        public MainForm()
        {
            InitializeComponent();
 
            obj = new DateAndTime();
            obj.Date = true;
            obj.Time = false;
        }
 
        private void btnOpen_Click(object sender, EventArgs e)
        {
            DateAndTime newObj = obj;
            ChildForm childForm = new ChildForm(newObj);
 
            childForm.ShowDialog(this);
        }
    }
public partial class ChildForm : Form
    {
        private DateAndTime parentObj = null; //parent object
        private DateAndTime newObj = null; //deep copy
 
        public bool Date
        {
            get { return chbDate.Checked; }
            set { chbDate.Checked = value; }
        }
 
        public bool Time
        {
            get { return chbTime.Checked; }
            set { chbTime.Checked = value; }
        }
 
        public ChildForm(DateAndTime obj)
        {
            InitializeComponent();
 
            parentObj = obj; //references are equal
            newObj = obj.DeepClone(); //deep copy made by binary serialization
            
            Date = newObj.Date;
            Time = newObj.Time;
        }
 
        private void btnSave_Click(object sender, EventArgs e)
        {
            parentObj = newObj;
 
            parentObj.Date = newObj.Date;
            parentObj.Time = newObj.Time;
        }
    }
Имеется две формы, при нажатии на кнопку Open на первой форме открывается вторая форма и в конструктор класса передается объект класса DateAndTime. После изменения настроек и их сохранения все изменения должны быть отражены и в объекте, который передавался в конструктор класса, но этого не происходит. Подскажите, пожалуйста, почему так происходит и что я сделал не так? Если не создавать полной копии и просто скопировать все поля класса DateAndTime в конструкторе, то все работает, как и ожидалось.

Решение задачи: «Создание полной копии (deep copy) объекта»

textual
Листинг программы
public ChildForm(ref DateAndTime obj)
        {
            InitializeComponent();
 
            parentObj = obj; //references are equal
            newObj = obj.DeepClone(); //deep copy made by binary serialization
            
            Date = newObj.Date;
            Time = newObj.Time;
        }
... 
//Ну и вызов
private void btnOpen_Click(object sender, EventArgs e)
        {
            DateAndTime newObj = obj;
            ChildForm childForm = new ChildForm(ref newObj);
 
            childForm.ShowDialog(this);
            obj = newObj; // теперь эти переменные ссылаются на новый - deep copy - oбъект
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4.111 из 5
Похожие ответы