Компьютерные книги
Главное меню
Главная Поиск по сайту Добавить материал О нас Карта книг Карта сайта
Реклама
computersbooks.net -> Добавить материал -> Языки программирования -> Ватсон К. -> "С#" -> 123

С# - Ватсон К.

Ватсон К. С# — Лори, 2005 . — 879 c.
ISBN 1-861004-98-2
Скачать (прямая ссылка): vatsonc2005.pdf
Предыдущая << 1 .. 117 118 119 120 121 122 < 123 > 124 125 126 127 128 129 .. 404 >> Следующая


Это может быть продемонстрировано с помощью следующего кода:

Cloner щ/Source * newCloner(5); '

Cloner nyTarget * (Cloner)oy&ource.GetCopyО;

Console.WriteLine(*qyTarget.HyContent.Val ¦ (0)*, щ/Taraet.HyContent.Val)j JHySour s ilyContent. Val ¦= 2;

Console,HritaLine<'myTarget.HyContent.val ¦ (0}', myTarget.HyContent.Val);

Четвертая строка кода, в которой значение присваивается mySource.MyContent.val — общему полю val общего поля 4yContent исходного объекта, изменяет также и значение myTarget.MyContent.Val. Это происходит потому, ЧТО щу5оигсе.HyContent ссылается на ТОТ же самый экземпляр объекта, ЧТО И iKyTarget.MyContent, Поэтому исполнение приведенного выше кода приведет к следующим результатам:

myTarget. My Content. Val = 5 myTarget.MyContent.Val = 2
260

Глава 11

Для того чтобы избежать возникновения подобной ситуации, следует воспользоваться глубоким копированием. Мы можем просто внести соответствующие изменения в метод Getcopy{), который использовался в предыдущем примере, однако более предпочтительным является стандартный подход, принятый в .NET Framework. Для этого нам потребуется реализовать интерфейс icioneabia, у которого имеется единственный метод clone о. У названного метода нет параметров, а возвращает он значение типа объекта, что делает его сигнатуру идентичной использовавшемуся выше методу GetCopyf).

Несколько изменив созданные нами классы, мы можем написать следующий код, выполняющий глубокое копирование:

public class Content (

public int Val;

)

public class Cloner t icloneable (

public Content MyContent = new Content()j public Cloner(int newVal)

{

MyContent. Val = newVal;

)

public object Clone()

{

Cloner clonedCloner ” new Cloner (MyContent. Val);

return ClonedCloner;

>

В данном случае мы создали новый объект cloner, используя для этого поле val объекта Content, содержащегося в исходном объекте cloner (MyContent). Это поле имеет ссылочный тип, поэтому более глубокого копирования не требуется.

Воспользовавшись программой, аналогичной тон, которая использовалась для тестирования поверхностного копирования, и заменив в иен метод Getcopy () методом clone (), мы получим следующие результаты:

myTarget.MyContent. Val = 5 myTarget.MyContent.Val = 5

На этот раз внутренние объекты являются независимыми друг от друга.

Обратите внимание, что в некоторых случаях — для более сложных систем объектов — могут потребоваться рекурсивные вызовы метода cione(). Например, если для поля HyContent класса cioner также необходимо выполнить глубокое копирование, то нам может понадобиться следующий код:

public class Cloner ; iCloneable < , public Content MyContent = new Content!);

public object Clone()

(

Cloner clonedCloner * new Cloner (); clonedCloner .MyContent ¦= HyContent.Clone (); return clonedCloner;

) .
Дополнительные сведения о классах

261

В данном случае нами используется конструктор по умолчанию — для упрощения синтаксиса, необходимого для создания нового объекта cioner, Для того чтобы этот код заработал, нам также потребуется реализовать интерфейс icloneable в классе content.

Усовершенствование CardLib, часть 3

Давайте применим полученные знания на практике, реализовав возможность копирования Card, cards н Deck с использованием интерфейса icloneable. Это может оказаться полезным в некоторых карточных играх, где требуются две колоды - карт, которые совершенно не обязательно должны ссылаться на одни и те же объекты Card (хотя можно предположить, что нам понадобится другая колода, в которой порядок следования карт должен быть точно таким же, как н в первой).

Реализация функциональной возможности создания копий для класса card в chilcnrdLib оказывается простои, поскольку вполне достаточно поверхностного копирования (в классе card содержатся только данные значимого типа в виде полей). Нам потребуется только внести следующие изменения в определение класса:

public class Card : icloneable

public object Cloned ?

return MemberwiseClone () ;

)

Обратите внимание, что данная реализация интерфейса icloneable предоставляет просто поверхностное копирование. Никаких правил, определяющих, что именно должно происходить в методе cione(), не существует, и это вполне подходит для наших целей.

Теперь нам необходимо реализовать интерфейс icloneable для класса семейства cards. Это оказывается несколько сложнее, поскольку данная процедура включает в себя создание копий всех объектов card исходного семейства и, следовательно, возникает необходимость глубокого копирования:

public class Cards : CollectionBase, icloneable

public object Clone() t

Cards newCards = new Cards () j foreach (Card sourceCard in List)

(

newCarda.Add((Card)sourceCard.СloneО)i

>

return newCards;

Наконец, пам понадобится реализовать интерфейс icloneable для класса Deck. Здесь возникает небольшая проблема: в классе Deck отсутствует какой-либо способ изменения содержащихся о нем карт, кроме тасования колоды. Например, не существует способа, позволяющего внести изменения в экземпляр класса Deck, расположив в нем карты заданным образом, Для того чтобы обойти эту проблему, мы определяем для класса Deck новый частный конструктор, разрешающий передавать определенное семейство cards при создании экземпляра объекта Deck. В этом случае код. который позволит создавать копни данного класса, будет иметь следующий вид:
Предыдущая << 1 .. 117 118 119 120 121 122 < 123 > 124 125 126 127 128 129 .. 404 >> Следующая
Книги
Web-программирован-
ие
Аппаратное обеспечение Графика Руководство по П.О. Самоучитель Теория программирования Фотошоп Языки программирования
Новые книги
Вирт Н. "Систематическое программирование " (Теория программирования)

Эком "Microsoft Excel 2000 шаг за шагом Русская версия самоучитель " (Самоучитель)

Поляков А.Ю. "Методы и алгоритмы компьютерной графики в примерах Vizual C++" (Графика)

Баяковский Ю.М. "Графическая библиотека Open GL " (Графика)

Валиков А. "Технология " (Языки программирования)
Авторские права © 2013 ComputersBooks. Все права защищены.