Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

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

Что касается последнего (ISerializable) и его использование, я процитировал из Страница MSDN для интерфейса:

Любой класс, который может быть сериализован , должен быть помечен атрибутом SerializableAttribute.Если классу необходимо управлять процессом сериализации , он может реализовать интерфейс ISerializable.Программа форматирования вызывает GetObjectData во время сериализации и заполняет предоставленную SerializationInfo всеми данными, необходимыми для представления объекта.Программа форматирования создает SerializationInfo с типом объекта на графике.Объекты, которым необходимо отправлять прокси для себя, могут использовать FullTypeName и AssemblyName методы SerializationInfo для изменения передаваемой информации.

В случае наследования класса возможно сериализовать класс, который является производным от базового класса, который реализует ISerializable.В этом случае производный класс должен вызывать реализацию базового класса GetObjectData внутри своей реализации GetObjectData.В противном случае данные из базового класса не будут сериализованы.

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

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

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

Спасибо Марку и Папе за комментарии, я немного поторопился со своим первым ответом.

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top