|
Программирование >> Программирование с использованием ajax
public object Clone 0 { Deck newDeck = new Deck (cards. Clone () as Cards) ; return newDeck; private Deck (Cards newCards) { cards = newCards; Опять-таки, вы можете испробовать весь этот код в действии с помощью какого-нибудь простого клиентского кода (который, как и раньше, должны разместить внутри метода Main () соответствующего, предназначенного для тестирования, клиентского проекта): Deck deckl = new DeckO ; Deck deck2 = (Deck)deckl.Clone (); Console.WriteLine( The first card in the original deck is: {0} , Первая карта в исходной колоде deckl.GetCard(О)); Console.WriteLine ( The first card in the cloned deck is: {0} , Первая карта в клонированной колоде deck2.GetCard(0)); deckl.Shuffle О; Console.WriteLine( Original deck shuffled. ); Исходная колода перемешана Console.WriteLine ( The first card in the original deck is: {0} , deckl.GetCard(0)); Console.WriteLine( The first card in the cloned deck is: {0} , deck2.GetCard(0)); Console.ReadKey0; Вывод будет выглядеть примерно так, как показано на рис. 11.5. Рис. 11.5. Тестирование добавленной возможности клонирования И, наконец, реализуйте интерфейс ICloneable для класса Deck. Обратите внимание на наличие здесь одной небольшой проблемы: этот класс не предусматривает никакой возможности для изменения содержащихся в нем карт, кроме их тасования. Например, не существует никакой возможности изменить экземпляр Deck так, чтобы он имел определенный порядок карт. Чтобы обойти эту проблему, определите для класса Deck новый приватный конструктор, позволяющий передавать определенную коллекцию Card при создании экземпляра объекта Deck. Ниже приведен код, необходимый для реализации в этом классе возможности клонирования: public class Deck : ICloneable Сравнения В этом разделе рассматриваются два следующих возможных типа сравнений между объектами: □ сравнения типов; □ сравнения значений. Сравнения типов (т.е. определение того, что собой представляет объект или от чего он наследуется) важны во всех областях программирования на С#. Зачастую при передаче объекта (методу, например) то, что произойдет далее, зависит от того, объектом какого типа является данный объект. С этим уже не раз доводилось встречаться при передаче объектов как в этой, так и в предыдущих главах, но здесь будет продемонстрировано еще несколько полезных приемов. Сравнения значений тоже не раз было показано, по крайней мере, на примере простых типов. В случае сравнения значений объектов, однако, все выглядит немного сложнее. Для начала необходимо определить то, что именно подразумевается под сравнением, и что операции вроде > означают в контексте данных классов. Это особенно важно в случае коллекций, для которых может быть необходимо, чтобы объекты сортировались по какому-то условию, например, по алфавиту, или по какому-то более сложному алгоритму. Сравнение типов При сравнении объектов часто требуется знать их тип, поскольку это может позволить определять, является ли возможным сравнение значений. В главе 9 был представлен метод GetType (), который все классы наследуют от базового класса System. Ob j ect, и то, как он может использоваться вместе с операцией typeof () для определения типов объектов (и выполнения в зависимости от этого того или иного действия): if (myObj.GetTypeО == typeof(MyComplexClass)) { myObj является экземпляром класса MyComplexClass. Еще там было показано и то, как с помощью стандартной реализации метода ToString О , также унаследованного от базового класса System.Object, можно получать строковое представление типа объекта. Эти строки тоже можно сравнивать, но такой подход является довольно громоздким. В данном разделе будет продемонстрирован более короткий удобный способ, предусматривающий применение операции is. Он позволяет создавать гораздо более удобный для восприятия код, а также просматривать базовые классы. Перед рассмотрением операции is, однако, необходимо ознакомиться с процессами, которые часто происходят за кулисами при работе с типами-значениями (в отличие от ссылочных типов), а именно - упаковкой и распаковкой Упаковка и распаковка в главе 8 рассказывалось об отличиях между ссылочными типами и типами-значениями, а в главе 9 эти отличия даже были проиллюстрированы на примере сравнения структур (которые представляют собой типы-значения) и классов (являющихся ссылочными типами). Упаковкой (boxing) называется процесс преобразования типа-значения в тип System.Object или в тип интерфейса, который реализуется данным типом-значением, а распаковкой (unboxing) - соответственно, процесс обратного преобразования. Например, предположим, что имеется структура следующего типа: struct MyStruct public int Val; Упаковать структуру такого типа можно путем ее помещения в переменную типа object: MyStruct valTypel = new MyStruct (); valTypel.Val = 5; object refType = valTypel; Здесь сначала создается новая переменнгш (valTypel) типа MyStruct, затем ее члену Val присваивается новое значение, после чего она упаковывается в переменную типа object (refТуре). Объект, созданный путем упаковки переменной подобным образом, будет содержать ссылку на копию переменной valType, а не на исходную переменную valType. Удостовериться в этом можно, изменив содержимое исходной структуры, а затем распаковав содержащуюся в объекте структуру в новую переменную и просмотрев ее содержимое: valTypel.Val = 6; MyStruct valType2 = (MyStruct)refType; Console.WriteLine( valType2.Val = {0} , valType2.Val); Этот код приведет к получению следующего вывода: valType2.Val = 5 В случае присваивания ссылочного типа объекту, однако, поведение будет другим. Увидеть это можно, превратив MyStruct в класс (не обращая внимания на то, что тогда имя для этого класса является не совсем подходящим): class MyStruct public int Val; Если не вносить изменений в показанный ранее клиентский код (и, опять-таки, не обращать в нем внимания на неподходящие имена для переменных), это приведет к получению следующего вывода: valType2.Val = 6 Типы-значения еще можно упаковывать и в типы интерфейсов, разумеется, при условии, что они реализуют эти интерфейсы. Например, предположим, что тип MyStruct реализует интерфейс IMylnterface, как показано ниже: interface IMylnterface struct MyStruct : IMylnterface public int Val; Тогда упаковать его в тип IMylnterface можно следующим образом: MyStruct valTypel = new MyStruct (); IMylnterface refType = valTypel;
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |