Читать «ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание» онлайн - страница 409

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

[Seriаlizable]

class MyStringData: ISerializable {

 public string dataItemOne, dataItemTwo;

 public MyStringData() {}

 private MyStringData(SerializationInfo si, StreamingContext ctx) {

  // Регидратация члена из потока.

  dataItemOne = si.GetString(First_Item").ToLower();

  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() не требуется, чтобы элементы данных назывались одинаково с внутренними членами-переменными типа. Это может оказаться полезным тогда, когда нужно выделять данные из сохраненного формата. При этом не следует забывать о том, что для получения значений из приватного конструктора необходимо использовать имена, которые назначаются в рамках 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) {