Кажется, я могу сериализовать классы, у которых нет этого интерфейса, поэтому я не понимаю его назначение.
В чем смысл интерфейса ISerializable?
Ответ 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.