Добавить в цитаты Настройки чтения

Страница 169 из 502

Как упоминалось в главе 9, если перегружается оператор ==, то обычно приходится переопределять методы Equals(object) и GetHashCode(), поскольку чаще всего требуется, чтобы метод Equals(object) и оператор == функционировали одинаково. Когда же переопределяется метод Equals(object), то следует переопределить и метод GetHashCode(), чтобы оба метода оказались совместимыми.

Метод ToString() возвращает символьную строку, содержащую описание того объекта, для которого он вызывается. Кроме того, метод ToString() автоматически вызывается при выводе содержимого объекта с помощью метода WriteLine(). Этот метод переопределяется во многих классах, что позволяет приспосабливать описание к конкретным типам объектов, создаваемых в этих классах. Ниже приведен пример применения данного метода.

<b>// Продемонстрировать применение метода ToString()</b>

<b>using System;</b>

<b>class MyClass {</b>

<b>  static int count = 0; </b>

<b>  int id;</b>

<b>  public  MyClass() {</b>

<b>    id = count; </b>

<b>    count++;</b>

<b>  }</b>

<b>  public override string ToString() {</b>

<b>    return &quot;Объект #&quot; + id + &quot; типа MyClass&quot;;</b>

<b>  }</b>

<b>}</b>

<b>class Test {</b>

<b>  static void Main() {</b>

<b>    MyClass ob1 = new MyClass();</b>

<b>    MyClass ob2 = new MyClass();</b>

<b>    MyClass ob3 = new MyClass();</b>

<b>    Console.WriteLine(ob1);</b>

<b>    Console.WriteLine(ob2);</b>

<b>    Console.WriteLine(ob3);</b>

<b>  }</b>

<b>}</b>

При выполнении этого кода получается следующий результат.

<b>Объект #0 типа MyClass</b>

<b>Объект #1 типа MyClass</b>

<b>Объект #2 типа MyClass</b>

Как пояснялось выше, все типы в С#, включая и простые типы значений, являются производными от класса object. Следовательно, ссылкой типа object можно воспользоваться для обращения к любому другому типу, в том числе и к типам значений. Когда ссылка на объект класса object используется для обращения к типу значения, то такой процесс называется упаковкой. Упаковка приводит к тому, что значение простого типа сохраняется в экземпляре объекта, т.е. "упаковывается" в объекте, который затем используется как и любой другой объект. Но в любом случае упаковка происходит автоматически. Для этого достаточно присвоить значение переменной ссылочного типа object, а об остальном позаботится компилятор С#.

Распаковка представляет собой процесс извлечения упакованного значения из объекта. Это делается с помощью явного приведения типа ссылки на объект класса object к соответствующему типу значения. Попытка распаковать объект в другой тип может привести к ошибке во время выполнения.

Ниже приведен простой пример, демонстрирующий упаковку и распаковку.

<b>// Простой пример упаковки и распаковки.</b>

<b>using System;</b>

<b>class BoxingDemo { </b>

<b>  static void Main() {</b>

<b>    int x;</b>

<b>    object obj;</b>

<b>    x = 10;</b>

<b>    obj = x; // упаковать значение переменной х в объект</b>

<b>    int у = (int)obj; // распаковать значение из объекта, доступного по </b>

<b>                // ссылке obj, в переменную типа int </b>

<b>    Console.WriteLine(у);</b>

<b>  }</b>

<b>}</b>

В этом примере кода выводится значение 10. Обратите внимание на то, что значение переменной х упаковывается в объект простым его присваиванием переменной obj, ссылающейся на этот объект. А затем это значение извлекается из объекта, доступного по его ссылке obj, и далее приводится к типу int.

Ниже приведен еще один, более интересный пример упаковки. В данном случае значение типа int передается в качестве аргумента методу Sqr(), который, в свою очередь, принимает параметр типа object.

<b>// Пример упаковки при передаче значения методу.</b>

<b>using System;</b>

<b>class BoxingDemo {</b>

<b>  static void Main() {</b>

<b>    int x; </b>

<b>    x = 10;</b>

<b>    Console.WriteLine(&quot;Значение x равно: &quot; + x);</b>

<b>    // значение переменной x автоматически упаковывается </b>

<b>    // когда оно передается методу</b><b> Sqr().</b>