ISerializable C#

Всем доброго времени суток. На связи Алексей Гулынин. В прошлой статье мы начали рассматривать что такое сериализация в C#. В данной статье я бы хотел поговорить про интерфейс ISerializable в C#. Напомню о том, что нужно сделать для того, чтобы сериализация работала корректно:
1) У класса должен быть дефолтный конструктор без параметров.
2) Этот класс должен быть помечен атрибутом "Serializable".
3) Если мы хотим сами решать, что сериализовать, а что нет — реализовываем интерфейс "ISerializable".
В этом интерфейсе определен метод "GetObjectData()". Это метод, который вызывается при сериализации. Внутри этого метода и определяется какие поля и куда добавлять. Для десериализации нужно реализовать ещё недефолтный конструктор с параметрами, которые совпадают с параметрами метода "GetObjectData()", т.е. этот метод будет вызываться, когда данные будут восстанавливаться.
На определенное поле можно повесить атрибут "NonSerialized". Это означает, что данное поле не будет участвовать в сериализации. По умолчанию все поля сериализуются.
Давайте закрепим это всё на примере кастомной сериализации класса:
// Не забываем подключать пространство имён // using System.Runtime.Serialization; [Serializable] public class Room : ISerializable { public double Width { get; set; } public double Length { get; set; } [NonSerialized] public int numberOfWindows; public bool hasFurniture { get; set; } // Конструктор по умолчанию public Room() { } // Метод, вызываемый при сериализации public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Width", this.Width); info.AddValue("Length", this.Length); info.AddValue("hasFurniture", this.hasFurniture); } // Конструктор, вызываемый при десериализации public Room(SerializationInfo info, StreamingContext context) { this.Width = (double)info.GetValue("Width", typeof(double)); this.Length = (double)info.GetValue("Length", typeof(double)); this.hasFurniture = (bool)info.GetValue("hasFurniture", typeof(bool)); } }
Посмотрим на реализацию метода "GetObjectData()". В этом методе что определить что именно и куда мы кладём при сериализации. В простейшем случае нужен только первый параметр "SerializationInfo". Он представляет из себя нечто похожее на коллекцию "Dictionary". Сюда с помощью метода "AddValue()" добавляется ключ и значение. А при десериализации это значение будет вытаскиваться по ключу.
"StreamingContext" — это объект, который содержит дополнительную информацию о потоке, в который записываются эти данные.С помощью метода GetValue() мы по ключу получаем значение. Вторым параметром здесь указывается тип данных.
Напоминаю, что в простейшем случае этот интерфейс реализовывать не нужно.
В данной статье вы узнали, как реализовать интерфейс ISerializable в C#.
На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.