Шрифт:
Типы, реализующие интерфейс ISerializable, должны также определять специальный конструктор в соответствии со следующим шаблоном.
Обратите внимание на то, что для области видимости этого конструктора указано private. Это вполне допустимо, поскольку форматтер получает доступ к этому члену независимо от его видимости. Эти специальные конструкторы чаще всего обозначаются как приватные, чтобы обеспечить невозможность случайного создания объекта пользователем объекта с помощью такого конструктора. Заметьте, что первый параметр этого конструктора является (как и ранее) экземпляром типа SerializationInfo.
Второй параметр этого специального конструктора является типом StreamingContext, содержащим информацию об источнике или пункте назначения битов. Самым информативным членом этого типа является свойство State, которое представляет значение из перечня StreamingContextStates. Значения этого перечня соответствуют базовой композиции текущего потока.
Честно говоря, если вашей задачей разработки не является низкоуровневый пользовательский сервис удаленного доступа, вам вряд ли придется обращаться к указанному перечню непосредственно. Тем не менее, ниже приводятся имена элементов перечня StreamingContextStates (подробности его описания можно найти в документации .NET Framework 2.0 SDK).
Чтобы иллюстрировать возможности настройки процесса сериализации с помощью ISerializable, предположим, что у нас есть тип класса, который определяет два элемента строковых данных. Кроме того, предположим, что все символы этих строк должны сохраняться в поток в верхнем регистре, а восстанавливаться из потока – в нижнем. Чтобы учесть эти требования, вы можете реализовать ISerializable так. как показано ниже (не забудьте указать using для пространства имен System.Runtime.Serialization).
Обратите внимание на то, что при "наполнении" типа SerializationInfo в методе GetObjectData не требуется, чтобы элементы данных назывались одинаково с внутренними членами-переменными типа. Это может оказаться полезным тогда, когда нужно выделять данные из сохраненного формата. При этом не следует забывать о том, что для получения значений из приватного конструктора необходимо использовать имена, которые назначаются в рамках GetObjectData.
Чтобы проверить пользовательские настройки, предположим, что вы сохранили экземпляр MyStringData с помощью SoapFormatter. Заглянув в результирующий файл *.soap, вы увидите, что строковые поля в нем действительно представлены в верхнем регистре.
Настройка параметров сериализации с помощью атрибутов
Хотя реализация интерфейса ISerializable в .NET 2.0 все еще допустима, для настройки процесса сериализации теперь более предпочтительным считается определение методов, наделенных одним из целого ряда новых атрибутов, связанных с задачами сериализации (это атрибуты [OnSerializing], [OnSerialized], [OnDeserializing] и [OnDeserialized]). Использование этих атрибутов оказывается менее громоздким, чем реализация ISerializable, поскольку тогда не возникает необходимости вручную взаимодействовать с поступающим параметром SerializationInfo. Вместо этого вы получаете возможность непосредственно изменять данные состояния во время воздействия форматтера на тип.