ISerializable C#

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#.

На связи был Алексей Гулынин, оставляйте свои комментарии, увидимся в следующих статьях.


Комментарии:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *