Страницы

Поиск по вопросам

среда, 31 октября 2018 г.

Зачем нужен атрибут [Serializable] и что он делает?

У всех классов, экземпляры которых должны/могут быть сохранены через BinaryFormater, обязан быть этот самый атрибут [Serializable]. Зачем он нужен?
Нет, конечно, ясно, что он говорит среде CLR, мол, тип есть сериализуемый, поэтому, будь добра (среда) и сериализируй!
В моем представлении, почти на пальцах, этот атрибут помогает MSV дописать и реализовать GetObjectData(SerializationInfo info, StreamingContext context) из интерфейса ISerializable для каждого поля в классе. Например, так:
public override void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("Name", name); info.AddValue("BDate", BDate); info.AddValue("Price", Price); }
И реализовать конструктор для десериализации, вот так:
public Engineer(SerializationInfo info, StreamingContext context) : base(info.GetString("Name"), info.GetDateTime("BDate")) { Price = info.GetDecimal("Price");
}
НО, даже если и интерфейс ISerializable ты реализовал, то атрибут все равно нужен. CA2237: MarkISerializableTypesWithSerializable
Что же он все таки делает, так сказать, под капотом?


Ответ

В дополнение к ответу @Alexander Petrov, процитирую MSDN (в собственном переводе):
Применяйте атрибут SerializableAttribute к типу для того, чтобы указать, что экземпляры этого типа разрешено сериализовывать. Если хотя бы один тип в графе сериализуемых объектов (то есть, тип корневого объекта или любого объекта, на который он внутри ссылается прямо или косвенно) не имеет этого атрибута, CLR выбросит SerializationException
Это предотвращает ошибки, связанные с непредусмотренной сериализацией типов, которые для сериализации вовсе не предназначены.
Почему такое необходимо для бинарной сериализации? Дело в том, что бинарная сериализация нарушает инкапсуляцию и работает напрямую с закрытыми полями. При этом, в отличие от вызова сеттера для публичного свойства, легко может быть нарушен инвариант типа. Например, если каждый экземпляр класса получает при создании уникальный номер, то бинарная десериализация склонирует этот самый номер, нарушив тем самым логику программы.
Чтобы избежать таких проблем, для участия типа в сериализации CLR требует осознанного решения программиста о том, что каждый конкретный может быть безопасно сериализирован.
(Информация частично взята из этого ответа.)

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

Отправить комментарий