13_1_C#_сериализация.pptx
- Количество слайдов: 16
Сериализация (Serialization): сохранение и восстановление объектов ü Сериализация - преобразование объекта или графа объектов в линейную последовательность байт для сохранения на некотором носителе или передачи по каналу связи для последующего восстановления. ü Десериализация – восстановление объекта.
Классы Binary. Formatter и SOAPFormatter ü Сериализацию обеспечивают методы интерфейса IFormatter, реализованные в классах-форматтерах: System. Object System. Runtime. Serialization. Formatters. Binary. Formatter System. Runtime. Serialization. Formatters. Soap. Formatter ü Binary. Formatter сохраняет объект в двоичном формате. При использовании двоичного формата обеспечивается высокая производительность. ü Soap. Formatter сохраняет объект в XML-документе, оформленном по стандарту SOAP (Simple Object Access Protocol). При использовании SOAP формата обеспечивается межплатформенность. ü Интерфейс System. Runtime. Serialization. IFormatter : public interface IFormatter { void Serialize( Stream serialization. Stream, object graph ); object Deserialize( Stream serialization. Stream ); … }
Сериализация : общая схема ü Сериализация: • cоздаем или получаем поток для сохранения объектов; • создаем форматтер; • вызываем метод Serialize для сериализации объектов в поток; • не забыть закрыть поток! Abc a = new Abc (3, "abc"); Abc [] arr = new Abc[2] {new Abc(2, "efg"), new Abc(3, "xyz")} ; File. Stream s. W = File. Create("Data. bin"); Binary. Formatter bin. F = new Binary. Formatter(); bin. F. Serialize(s. W, arr); s. W. Close();
Сериализация : общая схема -2 ü Сериализовать можно только объекты классов (структур, перечислений, делегатов), имеющих атрибут [Serializable]. ü Если производный класс имеет атрибут [Serializable], базовый класс также должен иметь этот атрибут. Все типы в графе объекта также должны иметь атрибут [Serializable]. ü Часть полей можно обозначить как [Non. Serialized] (атрибут можно прикрепить только к полю). [Serializable] class Data. Object { public int value; [Non. Serialized] public string name; // Поле name не будет сохранено … // и восстановлено }
Восстановление объектов : общая схема ü Десериализация: • cоздаем или получаем поток для восстановления объектов; • создаем форматтер; • вызываем метод Deserialize для восстановления объектов из потока; • не забыть закрыть поток! File. Stream s. R = File. Open. Read("Data. bin"); Binary. Formatter bin. R = new Binary. Formatter(); Abc da = (Abc) bin. R. Deserialize(s. R); Abc[] darr = (Abc[]) bin. R. Deserialize(s. R); s. R. Close();
Нестандартная(custom) сериализация ü Можно внести изменения в стандартный процесс сериализации. ü Для этого необходимо • реализовать в классе, объекты которого сериализуются, интерфейс ISerializable; public interface ISerializable { void Get. Object. Data (Serialization. Info info, Streaming. Context context); } • определить специальный конструктор T(Serialization. Info info, Streaming. Context context); ü Структура Serialization. Info содержит информацию об объекте, в том числе имя типа и сборки. ü Streaming. Context содержит информацию об источнике/приемнике
Некоторые методы структуры Serialization. Info public void Add. Value( string name, object value ); public void Add. Value( string name, double value ); public void Add. Value( string name, int value ); public void Add. Value( string name, object value, Type type ); public double Get. Double( string name ); public int Get. Int 32( string name ); public string Get. String( string name ); public object Get. Value( string name, Type type );
Нестандартная(custom) сериализация ü Метод Get. Object. Data явно сериализует данные объекта: public virtual void Get. Object. Data(Serialization. Info info, Streaming. Context context) { info. Add. Value("nt", nt); info. Add. Value("r", lst); info. Add. Value("name", name); } ü Конструктор вызывается при восстановлении объекта: public Custom. LAbc (Serialization. Info info, Streaming. Context context) { nt = info. Get. Int 32("nt"); name = info. Get. String ("name"); lst = (Array. List) info. Get. Value("r", typeof(Array. List)); r. Data(); }
Интерфейс IDeserialization. Callback ü Интерфейс IDeserialization. Callback поддерживается всеми версиями. NET Framework (1. 0 и выше). public interface IDeserialization. Callback { void On. Deserialization(object sender); } ü Если тип реализует интерфейс IDeserialization. Callback, метод On. Deserialization будет вызван после десериализации объекта. ü В этом методе можно выполнить необходимую инициализацию, например, присвоить значения полям объекта с атрибутом [Non. Serialized] (по умолчанию при десериализации объекта всем полям с атрибутом [Non. Serialized] присваиваются значения по умолчанию в соответствии с типом).
События в Binary. Formatter ü Класс Binary. Formatter поддерживает четыре события, связанных с сериализацией. ü Класс SOAPFormatter события не поддерживает. ü Схемы из статьи Juval Lowy “Format Your Way to Success with the. NET Framework Versions 1. 1 and 2. 0”- MSDN Magazine, October 2004.
События в Binary. Formatter Событие Serializing Serialized Deserializing Deserialized Вызов перед сериализацией после сериализации перед десериализацией после десериализации Атрибут [On. Serializing] [On. Serialized] [On. Deserializing] [On. Deserialized] ü Методы, которые работают как обработчики событий, должны иметь атрибут и сигнатуру void <Method Name>(Streaming. Context context); ü Атрибуты [On. Serializ…] не наследуются. ü Атрибуты [On. Serializi…] можно одновременно прикрепить к нескольким методам класса. ü К одному и тому же методу можно одновременно прикрепить и атрибут [On. Serializing] и атрибут [On. Serialized], но нет простого способа выяснить, для какого события был вызван метод.
Сериализация и версии сборки ü Для каждого сериализуемого объекта кроме его состояния (значения сериализуемых полей) сохраняется полное имя сборки и информация о версии сборки. ü При десериализации объекта загружается сборка и метаданные типа. ü Если сборка, в которой находится сериализуемый тип, не имеет строгого имени (strong name), форматеры полностью игнорируют информацию о версии. ü Для сборок со строгим именем при сериализации и десериализации версии сборок с типами должны быть согласованы.
Сериализация и версии сборки -2 ü В классе Binary. Formatter определено свойство Assembly. Format , которое дает возможность использовать только дружественное имя сборки (friendly name) без информации о версии и открытом ключе (public key token), даже если сборка имеет строгое имя: public Formatter. Assembly. Style Assembly. Format { get; set; } ü Перечисление Formatter. Assembly. Style: public enum Formatter. Assembly. Style { Full, Simple } ü Если значение свойства равно Formatter. Assembly. Style. Full, при десериализации выполняется проверка версии сборки. ü Если значение равно Formatter. Assembly. Style. Simple, при десериализации проверка версии сборки не выполняется.
Version Tolerant Serialization (VTS) ü В. NET Framework 1. x между метаданными типа, которые используются при сериализации и десериализации, должно быть полное соответствие. ü В. NET Framework 2. 0 в класс Binary. Formatter внесены изменения, которые допускают небольшие отличия в описании типа при сериализации и десериализации. ü Это позволяет сохранить совместимость, если через некоторое время сериализуемые типы немного модифицируются.
VTS: Толерантность по отношению к внешним или неожидаемым данным В примере • при сериализации данных была использована новая версия сборки с типом Address; • при десериализации данных используется старая версия сборки с типом Address; ü Binary. Formatter при десериализации пропустит поле Country. Field и не бросит исключение. // Старая версия типа [Serializable] public class Address { string Street; string City; } // Новая версия типа [Serializable] public class Address { string Street; string City; string Country. Field; }
VTS: Толерантность по отношению к пропущенным данным ü В примере • при сериализации данных была использована старая версия сборки с типом Address; • при десериализации данных используется новая версия сборки с типом Address; ü Binary. Formatter при десериализации присвоит полю Country. Field значение по умолчанию и не бросит исключение. // Старая версия типа [Serializable] public class Address { string Street; string City; } // Новая версия типа [Serializable] public class Address { string Street; string City; string Country. Field; }
13_1_C#_сериализация.pptx