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

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

<b>class Test : ICloneable {</b>

<b>  public X o;</b>

<b>  public int b;</b>

<b>  public Test(int x, int y) {</b>

<b>    o = new X(x);</b>

<b>    b = y;</b>

<b>  }</b>

<b>  public void Show(string name) {</b>

<b>    Console.Write(&quot;Значения объекта &quot; + name + &quot;: &quot;);</b>

<b>    Console.WriteLine(&quot;o.a: {0}, b: {1}&quot;, o.a, b);</b>

<b>  }</b>

<b>  // Создать полную копию вызывающего объекта,</b>

<b>  public object Clone() {</b>

<b>    Test temp = new Test(o.a, b);</b>

<b>    return temp;</b>

<b>  }</b>

<b>}</b>

<b>class CloneDemo {</b>

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

<b>    Test ob1 = new Test(10, 20);</b>

<b>    ob1.Show(&quot;ob1&quot;);</b>

<b>    Console.WriteLine(&quot;Сделать объект ob2 копией объекта ob1.&quot;);</b>

<b>    Test ob2 = (Test)ob1.Clone();</b>

<b>    ob2.Show(&quot;ob2&quot;);</b>

<b>    Console.WriteLine(&quot;Изменить значение ob1.о.а на 99, &quot; +</b>

<b>            &quot; а значение ob1.b — на 88.&quot;);</b>

<b>    ob1.o.a = 99;</b>

<b>    ob1.b = 88;</b>

<b>    ob1.Show(&quot;ob1&quot;);</b>

<b>    ob2.Show(&quot;ob2&quot;);</b>

<b>  }</b>

<b>}</b>

Ниже приведен результат выполнения этой программы.

<b>Значения объекта оb1: о.а: 10, b: 20</b>

<b>Сделать объект оb2 копией объекта оb1.</b>

<b>Значения объекта оb2: о.а: 10, b: 20</b>

<b>Изменить значение ob1.о.а на 99, а значение obl.b — на 88.</b>

<b>Значения объекта оb1: о.а: 99, b: 88</b>

<b>Значения объекта оb2: о.а: 10, b: 20</b>

Как следует из результата выполнения приведенной выше программы, объект оb2 является копией объекта оb1, но это совершенно разные объекты. Изменения в одном из них не оказывают никакого влияния на другой. Это достигается конструированием нового объекта типа Test, который выделяет новый объект типа X для копирования. При этом новому экземпляру объекта типа X присваивается такое же значение, как и у объекта типа X в оригинале.

Для получения неполной копии достаточно вызвать метод MemberwiseClone(), определяемый в классе Object из метода Clone(). В качестве упражнения попробуйте заменить метод Clone() в предыдущем примере программы на следующий его вариант.

<b>// Сделать неполную копию вызывающего объекта,</b>

<b>public object Clone()    {</b>

<b>  Test temp = (Test) MemberwiseClone();</b>

<b>  return temp;</b>

<b>}</b>

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

<b>Значения объекта ob1: о.а: 10, b: 20</b>

<b>Сделать объект оb2 копией объекта оb1.</b>

<b>Значения объекта оb2: о.а: 10, b: 20</b>

<b>Изменить значение ob1.о.а на 99, а значение obl.b — на 88.</b>

<b>Значения объекта ob1: о.а: 99, b:</b>

<b>88 Значения объекта оb2: о.а: 99, b: 20</b>

Как видите, обе переменные экземпляра о в объектах оb1 и оb2 ссылаются на один и тот же объект типа X. Поэтому изменения в одном объекте оказывают влияние на другой. Но в то же время поля b типа int в каждом из них разделены, поскольку типы значений недоступны по ссылке.

Интерфейсы IFormatProvider и IFormattable

В интерфейсе IFormatProvider определен единственный метод GetFormat(), который возвращает объект, определяющий форматирование данных в удобочитаемой форме текстовой строки. Ниже приведена общая форма метода GetFormat():

<b>object GetFormat(Type formatType)</b>

где formatType — это объект, получаемый для форматирования.

Интерфейс IFormattable поддерживает форматирование выводимых результатов в удобочитаемой форме. В нем определен следующий метод:

<b>string ToString(string format, IFormatProvider formatProvider)</b>

где format обозначает инструкции для форматирования, a formatProvider — поставщик формата.