C# 4.0 полное руководство - 2011 - Герберт Шилдт
Шрифт:
Интервал:
Закладка:
объект obj А оказывается таким же, как и объект objB. В противном случае возвращается значение false
protected Finalize()
Выполняет завершающие действия перед процессом “сборки мусора”. В C# метод Finalize () доступен через деструктор
public virtual int
Возвращает хеш-код, связанный с вызывающим
GetHashCode()
объектом
public Type GetTypeO
Получает тип объекта во время выполнения программы
protected object
Создает “неполную” копию объекта. При этом ко
MemberwiseClone()
пируются члены, но не объекты, на которые ссылаются эти члены
public static bool
Возвращает логическое значение true, если
ReferenceEquals(object objA,
объекты obj А и objB ссылаются на один и тот
object objB)
же объект. В противном случае возвращается логическое значение false
public virtual string
Возвращает строку, описывающую объект
ToString()
Класс Tuple
В версии .NET Framework 4.0 внедрен удобный способ создания групп объектов (так называемых кортежей). В основу этого способа положен статический класс Tuple, в котором определяется несколько вариантов метода Create () для создания кортежей, а также различные обобщенные классы типа Tuple<. . . >, в которых инкапсулируются кортежи. В качестве примера ниже приведено объявление варианта метода Create (), возвращающего кортеж с тремя членами.
public static Tuple<Tl, T2, T3>
Create<Tl, Т2, Т3> (Tl iteml, Т2 item2, ТЗ item3)
Следует заметить, что данный метод возвращает объект типа Tuple<Tl, Т2, Т3>, в котором инкапсулируются члены кортежа iteml, item2 и item3. Вообще говоря, кортежи оказываются полезными в том случае, если группу значений нужно интерпретировать как единое целое. В частности, кортежи можно передавать методам, возвращать из методов или же сохранять в коллекции либо в массиве.
Интерфейсы IComparable и IComparable<T>
Во многих классах приходится реализовывать интерфейс IComparable или IComparable<T>, поскольку он позволяет сравнивать один объект с другим, используя различные методы, определенные в среде .NET Framework. Интерфейсы IComparable и IComparable<T> были представлены в главе 18, где они использовались в примерах программ для сравнения двух объектов, определяемых параметрами обобщенного типа. Кроме того, они упоминались при рассмотрении класса Array ранее в этой главе. Но поскольку эти интерфейсы имеют особое значение и применяются во многих случаях, то ниже приводится их краткое описание.
Интерфейс IComparable реализуется чрезвычайно просто, потому что он состоит всего лишь из одного метода.
int CompareTo(object obj) /
В этом методе значение вызывающего объекта сравнивается со значением объекта, определяемого параметром obj. Если значение вызывающего объекта больше, чем у объекта obj, то возвращается положительное значение; если оба значения равны — нулевое значение, а если значение вызывающего объекта меньше, чем у объекта obj, — отрицательное значение.
Обобщенный вариант интерфейса IComparable объявляется следующим образом.
public interface IComparable<T>
В данном варианте тип сравниваемых данных передается параметру Т в качестве аргумента типа. В силу этого объявление метода CompareTo () претерпевает изменения и выглядит так, как показано ниже.
int CompareTo(Т other)
В этом объявлении тип данных, которыми оперирует метод CompareTo (), может быть указан явным образом. Следовательно, интерфейс IComparable<T> обеспечивает типовую безопасность. Именно по этой причине он теперь считается более предпочтительным в программировании на С#, чем интерфейс IComparable.
Интерфейс IEquatable<T>
Интерфейс IEquatable<T> реализуется в тех классах, где требуется определить порядок сравнения двух объектов на равенство их значений. В этом интерфейсе определен только один метод, Equals (), объявление которого приведено ниже.
bool Equals(Т other)
Этот метод возвращает логическое значение true, если значение вызывающего объекта оказывается равным значению другого объекта other, в противном случае — логическое значение false.
Интерфейс IEquatable<T> реализуется в нескольких классах и структурах среды .NET Framework, включая структуры числовых типов и класс String. Для реализации интерфейса IEquatable<T> обычно требуется также переопределять методы Equals (Object) и GetHashCode (), определенные в классе Object.
Интерфейс IConvertible
Интерфейс IConvertible реализуется в структурах всех типов значений, String и DateTime. В нем определяются различные преобразования типов. Реализовывать этот интерфейс в создаваемых пользователем классах, как правило, не требуется.
Интерфейс ICloneable
Реализовав интерфейс ICloneable, можно создать все условия для копирования объекта. В интерфейсе ICloneable определен только один метод, Clone (), объявление которого приведено ниже.
object Clone()
В этом методе создается копия вызывающего объекта, а конкретная его реализация зависит от способа создания копии объекта. Вообще говоря, существуют две разновидности копий объектов: полная и неполная. Если создается полная копия, то копия совершенно не зависит от оригинала. Так, если в исходном объекте содержится ссылка на другой объект О, то при его копировании создается также копия объекта О. А при создании неполной копии осуществляется копирование одних только членов, но не объектов, на которые эти члены ссылаются. Так, после создания неполной копии объекта, ссылающегося на другой объект О, копия и оригинал будут ссылаться на один и тот же объект О, причем любые изменения в объекте О будут оказывать влияние как на копию, так и на оригинал. Как правило, метод Clone () реализуется для получения полной копии. А неполные копии могут быть созданы с помощью метода MemberwiseClone (), определенного в классе Obj ect.
Ниже приведен пример программы, в которой демонстрируется применение интерфейса 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("o.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 obi = new Test(10, 20);
obi.Show("obi");
Console.WriteLine("Сделать объект ob2 копией объекта obi.");
Test ob2 = (Test) obi.Clone ();
ob2.Show("ob2");
Console.WriteLine("Изменить значение obi.о.а на 99, " +
" а значение obl.b — на 88.");
obi.о.a = 99; obl.b = 88;
obi.Show("obi"); ob2.Show("ob2");
}
}
, Ниже приведен результат выполнения этой программы.
Значения объекта оЫ: о.а: 10, Ь: 20 Сделать объект оЬ2 копией объекта оЫ.
Значения объекта оЬ2: о.а: 10, Ь: 20
Изменить значение obi.о.а на 99, а значение obl.b — на 88.
Значения объекта оЫ: о.а: 99, Ь: 88 Значения объекта оЬ2: о.а: 10, Ь: 20
Как следует из результата выполнения приведенной выше программы, объект оЬ2 является копией объекта оЫ, но это совершенно разные объекты. Изменения в одном из них не оказывают никакого влияния на другой. Это достигается конструированием нового объекта типа Test, который выделяет новый объект типа X для копирования. При этом новому экземпляру объекта типа X присваивается такое же значение, как и у объекта типа X в оригинале.