Как следует из результата выполнения приведенной выше программы, объект оb2 является копией объекта оb1, но это совершенно разные объекты. Изменения в одном из них не оказывают никакого влияния на другой. Это достигается конструированием нового объекта типа Test, который выделяет новый объект типа X для копирования. При этом новому экземпляру объекта типа X присваивается такое же значение, как и у объекта типа X в оригинале.
Для получения неполной копии достаточно вызвать метод MemberwiseClone, определяемый в классе Object из метода Clone. В качестве упражнения попробуйте заменить метод Clone в предыдущем примере программы на следующий его вариант. // Сделать неполную копию вызывающего объекта. public object Clone { Test temp = (Test) MemberwiseClone; return temp; }
После этого изменения результат выполнения данной программы будет выглядеть следующим образом. Значения объекта оb1: о.а: 10, b: 20 Сделать объект оb2 копией объекта оb1. Значения объекта оb2: о.а: 10, b: 20 Изменить значение оb1.о.а на 99, а значение оb1.b — на 88. Значения объекта оb1: о.а: 99, b: 88 Значения объекта оb2: о.а: 99, b: 20
Как видите, обе переменные экземпляра о в объектах оb1 и оb2 ссылаются на один и тот же объект типа X. Поэтому изменения в одном объекте оказывают влияние на другой. Но в то же время поля b типа int в каждом из них разделены, поскольку типы значений недоступны по ссылке. Интерфейсы IFormatProvider и IFormattable
В интерфейсе IFormatProvider определен единственный метод GetFormat, ко торый возвращает объект, определяющий форматирование данных в удобочитаемой форме текстовой строки. Ниже приведена общая форма метода GetFormat: object GetFormat(Type formatType)
где formatType — это объект, получаемый для форматирования. Интерфейс IFormattable поддерживает форматирование выводимых результатов в удобочитаемой форме. В нем определен следующий метод: string ToString(string format, IFormatProvider formatProvider)
где format обозначает инструкции для форматирования, a formatProvider — поставщик формата.
ПРИМЕЧАНИЕ Подробнее о форматировании речь пойдет в главе 22. Интерфейсы IObservable и IObserver
В версию .NET Framework 4.0 добавлены еще два интерфейса, поддерживающие шаблон наблюдателя: IObservable и IObserver. В шаблоне наблюдателя один класс (в роли наблюдаемого) предоставляет уведомления другому классу (в роли наблюдателя). С этой целью объект наблюдаемого класса регистрирует объект наблю дающего класса. Для регистрации наблюдателя вызывается метод Subscribe, ко торый определен в интерфейсе IObservable и которому передается объект типа IObserver, принимающий уведомление. Для получения уведомлений можно зарегистрировать несколько наблюдателей. А для отправки уведомлений всем за регистрированным наблюдателям применяются три метода, определенные в интер фейсе IObserver. Так, метод OnNext отправляет данные наблюдателю, метод OnError сообщает об ошибке, а метод OnCompleted указывает на то, что наблю даемый объект прекратил отправку уведомлений.
ГЛАВА 22. Строки и форматирование
В этой главе рассматривается класс String, положен ный в основу встроенного в C# типа string. Как из вестно, обработка символьных строк является неот ъемлемой частью практически всех программ. Именно по этой причине в классе String определяется обширный ряд методов, свойств и полей, обеспечивающих наиболее полное управление процессом построения символьных строк и манипулирования ими. С обработкой строк тесно связано форматирование данных в удобочитаемой форме. Используя подсистему форматирования, можно отфор матировать данные всех имеющихся в C# числовых типов, а также дату, время и перечисления. Строки в C
Вопросы обработки строк уже обсуждались в главе 7, и поэтому не стоит повторяться. Вместо этого целесообраз но дать краткий обзор реализации символьных строк в С#, прежде чем переходить к рассмотрению класса String.
Во всех языках программирования строка представляет собой последовательность символов, но конкретная ее реа лизация отличается в разных языках. В некоторых языках программирования, например в C++, строки представля ют собой массивы символов, тогда как в C# они являются объектами встроенного типа данных string. Следова тельно, string является ссылочным типом. Более того, string — это имя стандартного для среды .NET строково го типа System.String. Это означает, что в C# строке как объекту доступны все методы, свойства, поля и операторы, определенные в классе String.