Полное руководство. С# 4.0 - Шилдт Герберт
В основу типа object в С# положен класс object. Члены класса Object подробно рассматривались в главе 11, но поскольку он играет главную роль в С#, тоего методы ради удобства повторно перечисляются в табл. 21.16. В классе objectопределен конструкторpublic Object()
который создает пустой объект.
Таблица 21.16. Методы, определенные в классе ObjectКласс Tuple
В версии .NET Framework 4.0 внедрен удобный способ создания групп объектов(так называемых кортежей). В основу этого способа положен статический класс Tuple,в котором определяется несколько вариантов метода Create() для создания кортежей, а также различные обобщенные классы типа Tuple<...>, в которых инкапсулируются кортежи. В качестве примера ниже приведено объявление варианта методаCreate(), возвращающего кортеж с тремя членами.МетодНазначениеpublic virtual bool Equals(object obj)Возвращает логическое значение true, если вызывающий объект оказывается таким же, как и объект, определяемый параметром obj. В противном случае возвращается значение falsepublic static bool Equals(object objA, object objВ)Возвращает логическое значение true, если объект objА оказывается таким же, как и объект objВ. В противном случае возвращается значение falseprotected Finalize()Выполняет завершающие действия перед процессом "сборки мусора". В C# метод Finalize() доступен через деструкторpublic virtual int GetHashCode()Возвращает хеш-код, связанный с вызывающим объектомpublic Type GetType()Получает тип объекта во время выполнения программыprotected object MemberwiseClone()Создает "неполную" копию объекта. При этом копируются члены, но не объекты, на которые ссылаются эти членыpublic static bool ReferenceEquals(object objA, object objВ)Возвращает логическое значение true, если объекты objА и objВ ссылаются на один и тот же объект. В противном случае возвращается логическое значение falsepublic virtual string ToString()Возвращает строку, описывающую объектpublic static Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3)`Следует заметить, что данный метод возвращает объект типа Tuple<T1, Т2, Т3>, в котором инкапсулируются члены кортежа item1, item2 и item3. Вообще говоря, кортежи оказываются полезными в том случае, если группу значений нужно интерпретировать как единое целое. В частности, кортежи можно передавать методам, возвращать из методов или же сохранять в коллекции либо в массиве.Интерфейсы IComparable и IComparable
Во многих классах приходится реализовывать интерфейс IComparable илиIComparable, поскольку он позволяет сравнивать один объект с другим, используяразличные методы, определенные в среде .NET Framework. Интерфейсы IComparableи IComparable были представлены в главе 18, где они использовались в примерахпрограмм для сравнения двух объектов, определяемых параметрами обобщенноготипа. Кроме того, они упоминались при рассмотрении класса Array ранее в этой главе. Но поскольку эти интерфейсы имеют особое значение и применяются во многихслучаях, то ниже приводится их краткое описание.
Интерфейс IComparable реализуется чрезвычайно просто, потому что он состоитвсего лишь из одного метода.int CompareTo(object obj)
В этом методе значение вызывающего объекта сравнивается со значением объекта,определяемого параметром obj. Если значение вызывающего объекта больше, чем уобъекта obj, то возвращается положительное значение; если оба значения равны —нулевое значение, а если значение вызывающего объекта меньше, чем у объекта obj, —отрицательное значение.
Обобщенный вариант интерфейса IComparable объявляется следующим образом.public interface IComparable<T>
В данном варианте тип сравниваемых данных передается параметру Т в качестве аргумента типа. В силу этого объявление метода CompareTo() претерпевает измененияи выглядит так, как показано ниже.int CompareTo(Т other)
В этом объявлении тип данных, которыми оперирует метод CompareTo(), можетбыть указан явным образом. Следовательно, интерфейс IComparable обеспечивает типовую безопасность. Именно по этой причине он теперь считается более предпочтительным в программировании на С#, чем интерфейс IComparable.Интерфейс IEquatable
Интерфейс IEquatable<T> реализуется в тех классах, где требуется определитьпорядок сравнения двух объектов на равенство их значений. В этом интерфейсе определен только один метод, Equals(), объявление которого приведено ниже.bool Equals(T other)
Этот метод возвращает логическое значение true, если значение вызывающегообъекта оказывается равным значению другого объекта other, в противном случае —логическое значение false.
Интерфейс IEquatable реализуется в нескольких классах и структурах среды.NET Framework, включая структуры числовых типов и класс String. Для реализации интерфейса IEquatable обычно требуется также переопределять методыEquals(Object) и GetHashCode(), определенные в классе Object.Интерфейс IConvertible
Интерфейс IConvertible реализуется в структурах всех типов значений, String иDateTime. В нем определяются различные преобразования типов. Реализовывать этотинтерфейс в создаваемых пользователем классах, как правило, не требуется.Интерфейс ICloneable
Реализовав интерфейс ICloneable, можно создать все условия для копированияобъекта. В интерфейсе ICloneable определен только один метод, Clone(), объявление которого приведено ниже.object Clone()
В этом методе создается копия вызывающего объекта, а конкретная его реализациязависит от способа создания копии объекта. Вообще говоря, существуют две разновидности копий объектов: полная и неполная. Если создается полная копия, то копия совершенно не зависит от оригинала. Так, если в исходном объекте содержитсяссылка на другой объект О, то при его копировании создается также копия объекта О.А при создании неполной копии осуществляется копирование одних только членов,но не объектов, на которые эти члены ссылаются. Так, после создания неполной копии объекта, ссылающегося на другой объект О, копия и оригинал будут ссылаться наодин и тот же объект О, причем любые изменения в объекте О будут оказывать влияние как на копию, так и на оригинал. Как правило, метод Clone() реализуется дляполучения полной копии. А неполные копии могут быть созданы с помощью методаMemberwiseClone(), определенного в классе Object.
Ниже приведен пример программы, в которой демонстрируется применение интерфейса ICloneable. В ней создается класс Test, содержащий ссылку на объект класса X. В самом классе Test используется метод Clone() для создания полной копии.// Продемонстрировать применение интерфейса ICloneable.using System;class X { public int a; public X(int x) { a = x; }}class Test : ICloneable { public X о; public int b; public Test(int x, int y) { о = new X(x); b = y; } public void Show(string name) { Console.Write("Значения объекта " + name + ": "); Console.WriteLine("о.a: {0}, b: {1}", o.a, b); } // Создать полную копию вызывающего объекта. public object Clone() { Test temp = new Test(o.a, b); return temp; }}class CloneDemo { static void Main() { Test ob1 = new Test(10, 20); obi.Show("ob1"); Console.WriteLine("Сделать объект ob2 копией объекта оb1."); Test ob2 = (Test) ob1.Clone(); ob2.Show("ob2"); Console.WriteLine("Изменить значение оb1.о.а на 99, " + " а значение оb1.b - на 88."); оb1.о.а = 99; оb1.b = 88; оb1.Show("оb1"); ob2.Show("оb2"); }}
Ниже приведен результат выполнения этой программы.Значения объекта оb1: о.а: 10, b: 20Сделать объект оb2 копией объекта оb1.Значения объекта оb2: о.а: 10, b: 20Изменить значение оb1.о.а на 99, а значение оb1.b — на 88.Значения объекта оb1: о.а: 99, b: 88Значения объекта оb2: о.а: 10, b: 20
Как следует из результата выполнения приведенной выше программы, объект оb2является копией объекта оb1, но это совершенно разные объекты. Изменения в одномиз них не оказывают никакого влияния на другой. Это достигается конструированиемнового объекта типа Test, который выделяет новый объект типа X для копирования.При этом новому экземпляру объекта типа X присваивается такое же значение, каки у объекта типа X в оригинале.