Подтвердить что ты не робот

В чем смысл интерфейса ISerializable?

Кажется, я могу сериализовать классы, у которых нет этого интерфейса, поэтому я не понимаю его назначение.

4b9b3361

Ответ 1

ISerializable используется для предоставления пользовательской двоичной сериализации, обычно для BinaryFormatter (и, возможно, для целей удаленного использования). Без него он использует поля, которые могут быть:

  • неэффективна; если есть поля, которые используются только для эффективности во время выполнения, но могут быть удалены для сериализации (например, словарь может выглядеть по-разному при сериализации)
  • неэффективна; так как даже для необходимых полей необходимо включить много дополнительных метаданных
  • недействительным; если есть поля, которые не могут быть сериализованы (например, делегаты событий, хотя они могут быть отмечены [NonSerialized])
  • ломкими; ваша сериализация теперь привязана к именам полей, но поля предназначены для детализации реализации; см. также Обфускация, сериализация и автоматически реализованные свойства

Внедряя ISerializable, вы можете предоставить свой собственный механизм двоичной сериализации. Обратите внимание, что эквивалент xml это IXmlSerializable, используемый XmlSerializer и т.д.

Для целей DTO следует избегать BinaryFormatter - такие вещи, как xml (через XmlSerializer или DataContractSerializer) или json, хороши, как и кросс-платформенные форматы, такие как буферы протоколов.

Для полноты, protobuf-net включает в себя крючки для ISerializable (позволяя вам использовать переносимый двоичный формат без написания большого количества кода), но BinaryFormatter не будет вашим первым выбором здесь в любом случае.

Ответ 2

Классы могут быть сериализованы в .NET одним из двух способов:

  • Маркировка класса с помощью SerializableAttribute и декорирование всех полей, которые вы не хотите сериализовать с помощью атрибута NonSerialized. (Как отмечает Марк Гравелл, BinaryFormatter, который является классом, обычно используемым для форматирования объектов ISerializable, автоматически сериализует все поля, если они специально не отмечены иначе.)
  • Внедрение интерфейса ISerializable для полной пользовательской сериализации.

Первое проще использовать, поскольку оно просто включает в себя маркировку объявлений с атрибутами, но ограничено по мощности. Последнее обеспечивает большую гибкость, но требует значительно больших усилий для реализации. Какой из них вы должны использовать, полностью зависит от контекста.

Что касается последнего (ISerializable) и его использования, я процитировал со страницы

Ответ 3

С помощью ISerializable вы можете писать собственные методы в своем объекте, чтобы взять сериализацию при выполнении двоичной сериализации, чтобы сериализовать ваши объекты по-другому, чем то, что сделает подход по умолчанию, используемый BinaryFormatter.

Другими словами, если подход по умолчанию сериализует ваш объект по-другому, чем то, как вы хотите его сериализовать как, вы можете реализовать ISerializable для полного контроля. Обратите внимание, что рука об руку с ISerializable, там также должен быть реализован пользовательский конструктор.

XmlSerialization, конечно, будет использовать только свойства, ISerializable не имеет ничего общего с сериализацией XML.

Спасибо Marc и Pop за комментарии, я немного поспешил с моим первым ответом.

Ответ 4

Чтобы сделать объект "переносимым", вы должны его сериализовать. Например, если вы хотите передать данные объекта с помощью .NET Remoting или Web Services, вам необходимо предоставить методы, которые сериализуют ваши данные объекта, уменьшая количество экземпляров объекта в переносимом формате, который представляет собой верное представление объекта.

Затем вы также можете взять сериализованное представление, перенести его в другой контекст, например, на другой компьютер, и перестроить исходный объект.

При реализации интерфейса ISerializable класс должен предоставить метод GetObjectData, который включен в интерфейс, а также специализированный конструктор, специализированный для принятия двух параметров: экземпляр SerializationInfo и экземпляр StreamingContext.

Если ваши классы не требуют мелкомасштабного управления своим состоянием объектов, вы можете просто использовать атрибут [Serializable]. Классы, требующие большего контроля над процессом сериализации, могут реализовать интерфейс ISerializable.