сериализация экземпляров типа
В этом разделе подробно рассматривается тема сериализации полей объекта. Эта
тема поможет вам понять нетривиальные приемы сериализации и десериализации,
которым посвящен остаток данной главы.
Для облегчения работы модуля форматирования в FCL включен тип
FormatterServices
из пространства имен
System.Runtime.Serialization
. Он
обладает только статическими методами и не допускает создания экземпляров. Вот
каким образом модуль форматирования автоматически сериализует объект, типу
которого назначен атрибут
SerializableAttribute
:
1. Модуль форматирования вызывает метод
GetSerializableMembers
класса
FormatterServices
:
public static MemberInfo[] GetSerializableMembers(
Type type, StreamingContext context);
Для получения открытых и закрытых экземплярных полей (исключая поля
с атрибутом
NonSerializedAttribute
) этот метод использует отражения. Он
возвращает массив объектов
MemberInfo
— по одному объекту на каждое сери-
ализуемое экземплярное поле.
2. Полученный массив объектов
System.Reflection.MemberInfo
передается ста-
тическому методу
GetObjectData
класса
FormatterServices
:
public static Object[] GetObjectData(Object obj, MemberInfo[] members);
678
Глава.24 .Сериализация
Этот метод возвращает массив
Object
, в котором каждый элемент определяет
значение поля сериализованного объекта. Массивы
Object
и
MemberInfo
парал-
лельны. То есть нулевой элемент массива
Object
представляет собой значение
члена, фигурирующего в массиве
MemberInfo
под нулевым индексом.
3. Модуль форматирования записывает в поток идентификатор сборки и полное
имя типа.
4. Модуль форматирования пересчитывает элементы двух массивов, записывая
в поток ввода-вывода имя каждого члена и его значение.
А вот как выглядит процедура автоматической десериализации объекта, тип
которого помечен атрибутом
SerializableAttribute
:
1. Модуль форматирования читает из потока ввода-вывода идентификатор сбор-
ки и полное имя типа. Если сборка еще не загружена в домен, он загружает ее
(как описано ранее). При невозможности загрузки появляется исключение
SerializationException
, и десериализация объекта останавливается. Если же
сборка успешно загружена, модуль форматирования передает статическому
методу
GetTypeFromAssembly
класса
FormatterServices
ее идентификатор
и полное имя типа:
public static Type GetTypeFromAssembly(Assembly assem, String name);
Метод возвращает объект
System.Type
, содержащий информацию о типе
десериализованного объекта.
2. Модуль форматирования вызывает статический метод
GetUninitializedObject
класса
FormatterServices
:
public static Object GetUninitializedObject(Type type);
Этот метод выделяет память под новый объект, но не вызывает его конструк-
тор. При этом все байты объекта инициализируются значением
null
или 0.
1. Тем же способом, что и раньше, модуль форматирования создает и инициа-
лизирует массив
MemberInfo
, вызывая метод
GetSerializableMembers
класса
FormatterServices
. Данный метод возвращает набор полей, которые были
сериализованы и теперь нуждаются в десериализации.
2. Из содержащихся в потоке ввода-вывода данных модуль форматирования соз-
дает и инициализирует массив
Object
.
3. Ссылки на только что размещенный в памяти объект, массив
MemberInfo
, и па-
раллельный ему массив
Object
со значениями полей передаются статическому
методу
PopulateObjectMembers
класса
FormatterServices
:
public static Object PopulateObjectMembers(
Object obj, MemberInfo[] members, Object[] data);
Этот метод перебирает элементы массивов, инициализируя каждое поле
соответствующим значением. В результате объект оказывается полностью де-
сериализованным.
Do'stlaringiz bilan baham: |