dataItemTwo = si.GetString("dataItemTwo").ToLower();
}
void ISerializable.GetObjectData(SerializatianInfo info, StreamingContext ctx) {
// Наполнение объекта SerializationInfo
// форматированными данными.
info.AddValue("First_Item", dataItemOne.ToUpper());
info.AddValue("dataItemTwo", dataItemTwo.ToUpper());
}
}
Обратите внимание на то, что при "наполнении" типа SerializationInfo в методе GetObjectData()
Чтобы проверить пользовательские настройки, предположим, что вы сохранили экземпляр MyStringData с помощью SoapFormatter. Заглянув в результирующий файл *.soap, вы увидите, что строковые поля в нем действительно представлены в верхнем регистре.
‹SOAP-ENV:Envelope xmlns:xsi="…"›
‹SOAP-ENV:Body›
‹a1:MyStringData id="ref-1" xmlns:a1="…"›
‹First_Item id="ref-3"›ЭTO НЕКОТОРЫЕ ДАННЫЕ.‹/First_Item›
‹dataItemTwo id="ref-4"›ЭTO НЕКОТОРЫЕ ДОПОЛНИТЕЛЬНЫЕ ДАННЫЕ‹/dataItemTwo›
‹/a1:MyStringData›
‹/SOAP-ENV:Body›
‹/SOAP-ENV:Envelope›
Настройка параметров сериализации с помощью атрибутов
Хотя реализация интерфейса ISerializable в .NET 2.0 все еще допустима, для настройки процесса сериализации теперь более предпочтительным считается определение методов, наделенных одним из целого ряда новых атрибутов, связанных с задачами сериализации (это атрибуты [OnSerializing], [OnSerialized], [OnDeserializing] и [OnDeserialized]). Использование этих атрибутов оказывается менее громоздким, чем реализация ISerializable, поскольку тогда не возникает необходимости вручную взаимодействовать с поступающим параметром SerializationInfo. Вместо этого вы получаете возможность непосредственно изменять данные состояния во время воздействия форматтера на тип.
При использовании этих атрибутов методы должны определяться так, чтобы они получали параметр StreamingContext и не возвращали ничего (в противном случае в среде выполнения генерируется соответствующее исключение). Обратите внимание на то, что не требуется учитывать все указанные атрибуты сериализации – можно учесть только те стадии сериализации, для которых следует выполнить перехват. Для примера рассмотрите новый тип [Serializable] с теми же требованиями, что и у MyStringData, но на этот раз с использованием атрибутов [OnSerializing] и [OnDeserialized].
[Serializable]
class MoreData {
public string dataItemOne, dataItemTwo;
[OnSerializing]
internal void OnSerializing(StreamingContext context) {
// Выполняется в процессе сериализации.
dataItemOne = dataItemOne.ToUpper();
dataItemTwo = dataItemTwo.ToUpper();
}
[OnDeserialized]
internal void OnDeserialized(StreamingContext, context) {
// Выполняется по завершении реконструкции объекта.
dataItemOne = dataItemOne.ToLower();
dataItemTwo = dataItemTwo.ToLower();
}
}
Если выполнись сериализацию этого нового типа, вы снова обнаружите, что данные сохраняются в верхнем регистре, а воcстанавливаются – в нижнем.
Исходный код. Проект СustomSerialization размещен в подкаталоге, соответствующем главе 17.
Поддержка версий сериализации объектов
В завершение обсуждения этой главы мы рассмотрим тему поддержки версий сериализации объектов. Чтобы понять, почему это необходимо, мы используем следующий сценарий. Предположим, что мы создали класс UserPrefs (он уже упоминался в начале главы) так, как показано ниже.
[Serializable]
class UserPrefs {
public string objVersion = "1.0";
public ConsoleColor BackgroundColor;
public ConsoleColor ForegroundColor;
public UserPrefs() {