Основы программирования на C#


Клонирование и интерфейс ICloneable


Клонированием называется процесс создания копии объекта, а копия объекта называется его клоном. Различают два типа клонирования: поверхностное (shallow) и глубокое (deep). При поверхностном клонировании копируется сам объект. Все значимые поля клона получают значения, совпадающие со значениями полей объекта; все ссылочные поля клона являются ссылками на те же объекты, на которые ссылается и сам объект. При глубоком клонировании копируется вся совокупность объектов, связанных взаимными ссылками. Представьте себе мир объектов, описывающих людей. У этих объектов могут быть ссылки на детей и родителей, учителей и учеников, друзей и родственников. В текущий момент может существовать большое число таких объектов, связанных ссылками. Достаточно выбрать один из них в качестве корня, и при его клонировании воссоздастся копия существующей структуры объектов.

Глубокое клонирование требует рекурсивной процедуры обхода существующей структуры объектов, тщательно отработанной во избежание проблемы зацикливания. В общем случае, когда есть несколько классов, являющихся взаимными клиентами, глубокое клонирование требует наличия в каждом классе рекурсивной процедуры. Эти процедуры взаимно вызывают друг друга. Я не буду в этой лекции приводить примеры, хотя среди проектов, поддерживающих книгу, есть и проект, реализующий глубокое клонирование, где объекты разных классов связаны взаимными ссылками.

Поверхностное клонирование можно выполнить достаточно просто. Наиболее простой путь - клонирование путем вызова метода MemberwiseClone, наследуемого от прародителя object. Единственное, что нужно помнить: этот метод защищен, он не может быть вызван у клиента класса. Поэтому клонирование нужно выполнять в исходном классе, используя прием обертывания метода.

Давайте обеспечим эту возможность для класса Person, создав в нем соответствующий метод:

public Person StandartClone() { Person p = (Person)this.MemberwiseClone(); return(p); }

Теперь клиенты класса могут легко создавать поверхностные клоны. Вот пример:

public void TestStandartClone() { Person mother = new Person("Петрова Анна"); Person daughter = new Person("Петрова Ольга"); Person son = new Person("Петров Игорь"); mother[0] = daughter; mother[1] = son; Person mother_clone = mother.StandartClone(); Console.WriteLine("Дети матери: {0}",mother.Fam); Console.WriteLine (mother[0].Fam); Console.WriteLine (mother[1].Fam); Console.WriteLine("Дети клона: {0}",mother_clone.Fam); Console.WriteLine (mother_clone[0].Fam); Console.WriteLine (mother_clone[1].Fam); }




Начало  Назад  Вперед