Console.ReadLine();

В приведенном далее выводе видно, что хотя типы значений действительно были изменены, внутренние ссылочные типы поддерживают одни и те же значения, т.к. они "указывают" на те же самые объекты в памяти (в частности, оба объекта имеют дружественное имя Му new Point):

***** Fun with Object Cloning *****

Cloned p3 and stored new Point in p4

Before modification:

p3: X = 100; Y = 100; Name = Jane;

ID = 133d66a7-0837-4bd7-95c6-b22ab0434509

p4: X = 100; Y = 100; Name = Jane;

ID = 133d66a7-0837-4bd7-95c6-b22ab0434509

Changed p4.desc.petName  and p4.X

After modification:

p3: X = 100; Y = 100; Name = My new Point;

ID = 133d66a7-0837-4bd7-95c6-b22ab0434509

p4: X = 9; Y = 100; Name = My new Point;

ID = 133d66a7-0837-4bd7-95c6-b22ab0434509

Чтобы заставить метод Clone() создавать полную глубокую копию внутренних ссылочных типов, нужно сконфигурировать объект, возвращаемый методом MemberwiseClone(), для учета имени текущего объекта Point (тип System.Guid на самом деле является структурой, так что числовые данные будут действительно копироваться). Вот одна из возможных реализаций:

// Теперь необходимо скорректировать код для учета члена.

public object Clone()

{

  // Сначала получить поверхностную копию.

  Point newPoint = (Point)this.MemberwiseClone();

  // Затем восполнить пробелы.

  PointDescription currentDesc = new PointDescription();

  currentDesc.PetName = this.desc.PetName;

  newPoint.desc = currentDesc;

  return newPoint;

}

Если снова запустить приложение и просмотреть его вывод (показанный далее), то будет видно, что возвращаемый методом Clone() объект Point действительно копирует свои внутренние переменные-члены ссылочного типа (обратите внимание, что дружественные имена у рЗ и р4 теперь уникальны):

***** Fun with Object Cloning *****

Cloned p3 and stored new Point in p4

Before modification:

p3: X = 100; Y = 100; Name = Jane;

ID = 51f64f25-4b0e-47ac-ba35-37d263496406

p4: X = 100; Y = 100; Name = Jane;

ID = 0d3776b3-b159-490d-b022-7f3f60788e8a

Changed p4.desc.petName  and p4.X

After modification:

p3: X = 100; Y = 100; Name = Jane;

ID = 51f64f25-4b0e-47ac-ba35-37d263496406

p4: X = 9; Y = 100; Name = My new Point;

ID = 0d3776b3-b159-490d-b022-7f3f60788e8a

Давайте подведем итоги по процессу клонирования. При наличии класса или структуры, которая содержит только типы значений, необходимо реализовать метод Clone() с использованием метода MemberwiseClone(). Однако если есть специальный тип, поддерживающий ссылочные типы, тогда для построения глубокой копии может потребоваться создать новый объект, который учитывает каждую переменную-член ссылочного типа.

<p id="AutBody_Root344">Интерфейс IComparable</p>

Интерфейс System.IComparable описывает поведение, которое позволяет сортировать объекты на основе указанного ключа. Вот его формальное определение:

// Данный интерфейс позволяет объекту указывать

// его отношение с другими подобными объектами

public interface IComparable

{

  int CompareTo(object o);

}

На заметку! Обобщенная версия этого интерфейса (IСоmраrаble<Т>) предлагает более безопасный в отношении типов способ обработки операций сравнения объектов. Обобщения исследуются в главе 10.

Создайте новый проект консольного приложения по имени ComparableCar, скопируйте классы Car и Radio из проекта SimpleException, рассмотренного в главе 7, и поменяйте пространство имен в каждом файле класса на ComparableCar. Обновите класс Car, добавив новое свойство для представления уникального идентификатора каждого автомобиля и модифицированный конструктор:

Перейти на страницу:

Похожие книги