Сериализация и управление версиями объектов в С#

Если я хочу сериализовать объект, я должен использовать атрибут [Serializable], и все переменные-члены будут записаны в файл. Что я не знаю, как выполнять управление версиями, например. если я добавлю новую переменную-член (переименую переменную или просто удалю переменную), а затем я открою (десериализую) файл, как я могу определить версию объекта/файла, чтобы я мог правильно установить новый элемент или выполнить некоторую миграцию? Как я могу определить, что переменная была инициализирована во время загрузки или нет (игнорируется десериализатором).

Я знаю, что существуют толерантные к версии версии, и я могу отмечать переменные с атрибутом [OptionalField(VersionAdded = 1)]. Если я открою старый файл, инфраструктура будет игнорировать эту необязательную (новую переменную), и она будет равна нулю /null. Но опять же, как я могу определить, инициализирована ли переменная загрузкой или она была проигнорирована.

Я могу записать номер версии класса/объекта в поток. Используйте подход ISerializable, а в методе constructor(SerializationInfo oInfo, StreamingContext context) - этот номер версии. Это точно скажет мне, что такое версия класса в потоке.

Однако я ожидал, что такое управление версиями уже реализовано инфраструктурой потоковой передачи в С#. Я попытался получить версию Assembly из SerializationInfo, но она всегда установлена ​​на текущую версию не на версию, которая использовалась, когда объект был сохранен.

Каков предпочтительный подход? Я нашел много статей в сети, но я не мог найти хорошее решение для этого, которое касается версий...

Любая помощь приветствуется Благодаря, Abyss

Ответ 1

Простите меня, если некоторые из того, что я пишу, слишком очевидны,

Прежде всего, пожалуйста! вы должны перестать думать, что вы сериализуете объект... Это просто неверно, поскольку методы, которые являются частью вашего объекта, не сохраняются. Вы сохраняете информацию - и так.. Только DATA.

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

Помимо проблемы с версией - не все может быть легко сериализовано.. попробуйте сериализовать тип System.Drawing.Color, и вы начнете понимать проблемы с более упрощенным механизмом сериализации .NET.

Если вы не планируете сериализовать что-то действительно простое, которое не планирует развиваться, я бы не использовал механизм сериализации, предоставляемый .NET.

Возвращаясь к вашему вопросу, вы можете прочитать здесь о способности к игнорированию версий: http://msdn.microsoft.com/en-us/library/ms229752(v=vs.80).aspx, который предоставляется для BinaryFormatter.

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

Но, наконец, я рекомендую вам либо использовать базу данных с Entity Framework для сохранения ваших данных, либо написать собственный плоский файловый менеджер. В то время как EF очень хорош для большинства решений, иногда вам может понадобиться что-то более легкое, чтобы сохранить что-то очень простое. (я подразумеваю, что я больше не вижу решения, где сериализация .NET может быть релевантной.)

Надеюсь, это поможет, удачи.