Какой смысл в интерфейсе ISerializable? - PullRequest
49 голосов
/ 01 мая 2009

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

Ответы [ 4 ]

65 голосов
/ 01 мая 2009

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

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

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

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

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

9 голосов
/ 01 мая 2009

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

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

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

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

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

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

5 голосов
/ 01 мая 2009

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

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

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

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

3 голосов
/ 01 мая 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...