Ответ
Клонирование — это процесс создания нового объекта, который является копией существующего. В C# различают два основных типа клонирования, которые важно понимать для корректной работы с данными.
1. Поверхностное копирование (Shallow Copy)
Создает новый объект, но копирует значения полей. Для полей-значений (int, struct) копируется само значение. Для полей-ссылок копируется только ссылка, поэтому исходный и клонированный объекты делят одни и те же вложенные объекты.
Стандартный способ: Использование защищенного метода Object.MemberwiseClone().
public class Person
{
public string Name; // Ссылочный тип
public Address HomeAddress; // Ссылочный тип (класс)
public Person ShallowClone()
{
// MemberwiseClone создает shallow copy
return (Person)this.MemberwiseClone();
}
}
// Использование:
var original = new Person { Name = "John", HomeAddress = new Address("Street 1") };
var shallowCopy = original.ShallowClone();
shallowCopy.Name = "Jane"; // Изменяется только копия
shallowCopy.HomeAddress.Street = "Street 2"; // Изменяет Address и у original, и у копии!
2. Глубокое копирование (Deep Copy)
Создает новый объект и рекурсивно создает копии всех объектов, на которые есть ссылки. В результате получается полностью независимая копия всего графа объектов.
Реализация требует ручных усилий или использования сериализации:
public Person DeepClone()
{
var clone = (Person)this.MemberwiseClone();
clone.Name = this.Name; // string неизменяем, можно просто присвоить
clone.HomeAddress = new Address(this.HomeAddress.Street); // Создаем новый объект Address
return clone;
}
Практический совет: Интерфейс ICloneable (object Clone()) считается устаревшим в контексте best practices, так как он не указывает, какой тип копирования реализуется. Гораздо яснее создавать явные методы ShallowClone() и DeepClone(). Для сложных графов объектов часто используют сериализацию (например, через System.Text.Json с настройкой ссылочной целостности) для реализации глубокого копирования.