Чтение онлайн

ЖАНРЫ

ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Троелсен Эндрю

Шрифт:

Предположим, что в класс JamesBondCar был добавлен конструктор с двумя аргументами, чтобы можно было установить некоторые начальные данные состояния (обратите внимание на то, что конструктор, заданный по умолчанию, был возвращен на место в соответствии с требованиями XmlSerializer),

[Serializable,

XmlRoot(Namespace = "http://www.intartechtraining.com")]

public class JamesBondCar: Car {

 public JamesBondCar(bool skyWorthy, bool seaWorthy) {

canFly = skyWorthy; canSubmerge = seaWorthy;

 }

 // Для XmlSerializer
нужен конструктор, заданный по умолчанию!

 public JamesBondCar{}

 …

}

При этом вы сможете сохранить любое число объектов JamesBondCar так.

static void Main(string[] args) {

 …

 // Сохранение объекта List‹› с набором JamesBondCar.

 List‹JamesBondCar› myCars = new List‹JamesBondCar›;

 myCars.Add(new JamesBondCar(true, true));

 myCars.Add(new JamesBondCar(true, false));

 myCars.Add(new JamesBondCar(false, true));

 myCars.Add(new JamesBondCar(false, false));

 fStream = new FileStream("CarCollection.xml", FileMode.Create, FileAccess.Write, FileShare.None);

 xmlFormat = new XmlSerializer(typeof(List‹JamesBondCar›), new Type[] {typeof(JamesBondCar), typeof(Car), typeof(Radio)});

 xmlFormat.Serialize(fStream, myCars);

 fStream.Close;

 Console.ReadLine;

}

Снова обращаем внимание на то, что по причине использования XmlSerializer требуется указать информацию типа для каждого из объектов, вложенных в корневой объект (которым в данном случае является List‹›). При использовании BinaryFormatter или SoapFormatter программная логика будет еще проще.

statiс void Main (string[] args) {

 …

 // Сохранение объекта List‹›(myCars) в двоичном формате.

 list‹JamesBondCar› myCars = new List‹JamesBondCar›;

 …

 BinaryFormatter binFormat = new BinaryFormatter;

 Stream fStream = new FileStream("AllMyCars.dat", FileMode.Create, FileAccess.Write, FileShare.None);

 binFormat.Serialize(fStream, myCars);

 fStream.Close;

 Console.ReadLine;

}

Превосходно! К этому моменту вам должно быть понятно, как использовать сервис сериализации объектов для упрощения процесса сохранения и восстановления данных вашего приложения. Теперь давайте выясним, как использовать пользовательские настройки процесса сериализации.

Исходный код. Проект SimpleSerialize размещен в подкаталоге, соответствующем главе 17.

Настройка процесса сериализации

В большинстве случаев типовая схема сериализации, предлагаемая платформой .NET, будет именно тем, что требуется. Тогда нужно просто применить атрибут [Serializable] и передать объектный граф выбранному средству форматирования. Но в некоторых случаях может потребоваться корректировка того, как обрабатывается объектный граф в процессе сериализации. Например, в соответствии с внутренними правилами вашей компании все поля данных должны сохраняться в формате верхнего регистра или, возможно, вы хотите добавить в поток дополнительные элементы данных, которые не проецируются непосредственно в поля сохраняемого объекта (это могут быть штампы времени, уникальные

имена или что-то иное).

Для непосредственного участия в управлении процессом сериализации объектов пространство имен System.Runtime.Serialization предлагает специальные типы. В табл. 17.2 описаны те из них, о которых вам следует знать.

Таблица 17.2. Основные типы пространства имен System.Runtime.Serialization

Тип Описание
ISerializable В .NET 1.1 реализация этого интерфейса была наиболее предпочтительным методом пользовательской сериализации объектов. В .NET 2.0 для настройки параметров процесса сериализации предпочтительнее использовать новое множество атрибутов (они будут описаны чуть позже)
ObjectIDGenerator Тип, генерирующий идентификаторы элементов объектного графа
OnDeserializedAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается сразу же после выполнения реконструкции объекта
OnDeserializingAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается в процессе выполнения реконструкции объекта
OnSerializedAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается сразу же после выполнения сериализации объекта
OnSerializingAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается в процессе сериализации
OptionalFieldAttribute Атрибут .NET 2.0, позволяющий указать поле типа, которое может отсутствовать в указанном потоке
SerializationInfo По сути, этот класс является "чемоданом свойств", содержащим пары имен и значений, представляющих состояние объекта в процессе сериализации

Более глубокий взгляд на сериализацию объектов

Перед тем как рассмотреть различные способы настройки параметров процесса сериализации, было бы полезно выяснить, что при этом происходит "за кулисами". Когда тип BinaryFormatter выполняет сериализацию объектного графа, этот тип отвечает за передачу в указанный поток следующей информации:

• абсолютных имен объектов графа (например, MyApp.JamesBondCar);

• имени компоновочного блока, определяющего объектный граф (например, MyApp.exe);

• экземпляра класса SerializationInfo, содержащего все данные, поддерживаемые членами объектного графа.

В процессе реконструкции объекта тип BinaryFormatter использует ту же информацию, извлеченную из соответствующего потока, для построения абсолютно точной копии объекта.

Замечание. Напомним, что SoapFormatter и XmlSerializer не сохраняют абсолютное имя типа и имя определяющего компоновочного блока. Эти типы заботятся только о сохранении открытых полей данных.

Общую картину можно представлять в виде диаграммы, показанной на рис. 17.3.

Рис. 17.3 Схема процесса сериализации

Кроме перемещения необходимых данных в поток и извлечения их из потока, средство форматирования (форматтер) анализирует члены объектного графа на наличие следующих элементов инфраструктуры.

• Выясняется, обозначен ли объект атрибутом [Serializable]. Если нет, то генерируется исключение SerializationException.

• Если объект обозначен атрибутом [Serializable], то выясняется, реализует ли объект интерфейс ISerializable. Если да, то для объекта вызывается GetObjectData.

Поделиться с друзьями: