Вход/Регистрация
ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание
вернуться

Троелсен Эндрю

Шрифт:

 object Clone;

}

Очевидно, что реализация метода Clone будет зависеть от объекта. Но базовые функциональные возможности оказываются одинаковыми: это копирование значений членов-переменных в новый экземпляр объекта и возвращение этого экземпляра пользователю. В качестве иллюстрации рассмотрите следующую модификацию класса Point.

// Теперь Point поддерживает клонирование.

public class Point: ICloneable {

 public int x, y;

 public Point{}

 public Point (int x, int y) { this.x = x; this.у = у; }

 // Возвращение копии данного объекта.

 public object Clone { return new Point(this.x, this.y); }

 public override string ToString { return String.Format("X = {0}; Y = {1}", x, у); }

}

С помощью указанного подхода можно создавать точные и независимые копии типа Point, как показано в следующем фрагменте программного кода.

static void Main (string[] args) {

 // Обратите внимание, Clone возвращает объект общего типа.

 // Для получении производного типа используйте явное преобразование.

 Point р3 = new Point(100, 100);

 Point р4 = (Point)р3.Clone;

 // Изменение p4.х (это не изменит р3.х).

 р4.х = 0;

 // Вывод объектов.

 Console.WriteLine(р3);

 Console.WriteLine(p4);

}

Текущая реализация Point решает все поставленные задачи, но вы можете немного усовершенствовать процесс. Введу того, что тип Point не содержит переменных ссылочного типа, можно упростить реализацию метода Clone, как показано ниже.

public object Clone {

 // Скопировать все поля Point "почленно".

 return this.MemberwiseClone;

}

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

Пример клонирования

Предположим, что класс Point содержит член ссылочного типа с именем PointDescription, обеспечивающий поддержку "понятного" имени объекта Point и его идентификационного номера в виде System.Guid (еcли у вас нет опыта применения COM, знайте, что GUID – глобально уникальный идентификатор – это статистически уникальное 128-разрядное значение). Вот соответствующая реализация.

// Этот класс описывает точку.

public class PointDescription {

 // Открыты для простоты.

 public string petName;

 public Guid pointID;

 public PointDescription {

this.petName = "Без имени";

pointID = Guid.NewGuid;

 }

}

При этом для учета новых элементов состояния в самом классе Point следует изменить метод ToString, а также операторы определения и создания ссылочного типа PointDescription. Чтобы позволить "внешнему миру" указать имя для Point, можно также модифицировать аргументы, передаваемые перегруженному конструктору.

public class Point: ICloneable {

 public int x, y;

 public PointDescription desc = new PointDescription;

 public Point{}

 public Point (int x, int y) {

this.x = x;

this.у = у;

 }

 public Point(int x, int y, string petname) {

this.x = x;

this.у = у;

desc.petName = petname;

 }

 public object Clone { return this.MemberwiseClone; }

 public override string ToString {

return string.Format("X = {0}; Y = {1}; Имя = (2};\nID = {3}\n", x, y, desc.petName, desc.pointID);

 }

}

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

  • Читать дальше
  • 1
  • ...
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: