Глава.24 .Сериализация
В конструируемый объект
SerializationInfo
модуль форматирования пере-
дает два параметра:
Type
и
System.Runtime.Serialization.IFormatterConverter
.
Первый параметр идентифицирует сериализуемый объект. Для уникальной иден-
тификации типа требуется два фрагмента данных: строковое имя типа и иденти-
фикатор его сборки (включающий имя сборки, ее версию, региональные стандарты
и открытый ключ). Готовый объект
SerializationInfo
получает полное имя типа
(запросив свойство
FullName
), сохраняя его в закрытом поле. Для получения пол-
ного имени типа используйте свойство
FullTypeName
класса
SerializationInfo
.
Аналогичным образом конструктор получает определяющую тип сборку (за-
прашивая сначала свойство
Module
класса
Type
, затем свойство
Assembly
класса
Module
и, наконец, свойство
FullName
класса
Assembly
), сохраняя полученную
строку в закрытом поле. Для получения идентификатора сборки используйте поле
AssemblyName
класса
SerializationInfo
.
ПриМеЧание
Задать.свойства.FullTypeName.и.AssemblyName.класса.SerializationInfo.не.всегда.
возможно .Для.изменения.типа.после.сериализации.рекомендуется.вызвать.метод.
SetType.класса.SerializationInfo.и.передать.ему.ссылку.на.желаемый.объект.Type .Это.
гарантирует.корректность.задания.полного.имени.и.определяющей.сборки .Пример.
применения.данного.метода.приводится.далее.в.этой.главе
После создания и инициализации объекта
SerializationInfo
модуль форма-
тирования передает ссылку на него в метод
GetObjectData
типа. Именно метод
GetObjectData
определяет, какая информация необходима для сериализации
объекта, и добавляет эту информацию к объекту
SerializationInfo
. Определение
необходимой для сериализации информации происходит при помощи одной из
множества перегруженных версий метода
AddValue
типа
SerializationInfo
. Для
каждого фрагмента данных, который вы хотите добавить, вызывается один метод
AddValue
.
Показанный далее код демонстрирует, каким образом тип
Dictionary,
TValue>
реализует интерфейсы
ISerializable
и
IDeserializationCallback
, до-
биваясь контроля над сериализацией и десериализацией своих объектов:
[Serializable]
public class Dictionary: ISerializable,
IDeserializationCallback {
// Здесь закрытые поля (не показанные)
private SerializationInfo m_siInfo; // Только для десериализации
// Специальный конструктор (необходимый интерфейсу ISerializable)
// для управления десериализацией
[SecurityPermissionAttribute(
SecurityAction.Demand, SerializationFormatter = true)]
protected Dictionary(SerializationInfo info, StreamingContext context) {
681
Управление.сериализованными.и.десериализованными.данными
// Во время десериализации сохраним
// SerializationInfo для OnDeserialization
m_siInfo = info;
}
// Метод управления сериализацией
[SecurityCritical]
public virtual void GetObjectData(
SerializationInfo info, StreamingContext context) {
info.AddValue("Version", m_version);
info.AddValue("Comparer", m_comparer, typeof(IEqualityComparer));
info.AddValue("HashSize", (m_ buckets == null) ? 0 : m_buckets.Length);
if (m_buckets != null) {
KeyValuePair[] array =
new KeyValuePair[Count];
CopyTo(array, 0);
info.AddValue(
"KeyValuePairs", array, typeof(KeyValuePair[]));
}
}
// Метод, вызываемый после десериализации всех ключей/значений объектов
public virtual void IDeserializationCallback.OnDeserialization(
Object sender) {
if (m_siInfo == null) return; // Никогда не присваивается,
// возвращение управления
Int32 num = m_siInfo.GetInt32("Version");
Int32 num2 = m_siInfo.GetInt32("HashSize");
m_comparer = (IEqualityComparer)
m_siInfo.GetValue("Comparer", typeof(IEqualityComparer));
if (num2 != 0) {
m_buckets = new Int32[num2];
for (Int32 i = 0; i < m_buckets.Length; i++) m_buckets[i] = -1;
m_entries = new Entry[num2];
m_freeList = -1;
KeyValuePair[] pairArray = (
KeyValuePair[]) m_siInfo.GetValue(
"KeyValuePairs", typeof(KeyValuePair[]));
if (pairArray == null)
ThrowHelper.ThrowSerializationException(
ExceptionResource.Serialization_MissingKeys);
for (Int32 j = 0; j < pairArray.Length; j++) {
if (pairArray[j].Key == null)
ThrowHelper.ThrowSerializationException(
ExceptionResource.Serialization_NullKey);
Insert(pairArray[j].Key, pairArray[j].Value, true);
}
} else { m_buckets = null; }
продолжение
682
Do'stlaringiz bilan baham: |