Стабильность сериализации .NET в разных версиях фреймворка

Проект, над которым я работаю, требует сериализации структуры данных перед завершением работы и восстановления ее состояния из этих сериализованных данных при повторном запуске.

В прошлом году мы создавали .NET 1.1 и столкнулись с сложной проблемой, когда

  • наш код работал на .NET 2.0
  • клиент обновил какое-то программное обеспечение, которое каким-то образом установило 1.1 по умолчанию
  • наш код работал на .NET 1.1 и не смог десериализовать свое сохраненное состояние

Эта конкретная проблема была «решена» путем запрета этого конкретного обновления программного обеспечения, и не должно быть проблемой сейчас, когда мы ориентируемся на платформу .NET 2.0 (так что мы не можем работать на 1.1).

Какова вероятность того, что эта сериализация может снова несовместимо измениться между 2.0 и более новыми фреймворками? Если мы используем <supportedVersion>, чтобы исправить наш код на 2.0.50727, каковы шансы изменений между 2.0.50727.1434 и 2.0.50727.nnnn (какой-нибудь будущий выпуск)? Сериализуемые структуры данных представляют собой массивы, карты, строки и т. Д. Из стандартных библиотек классов.

Кроме того, гарантировано ли, что платформа 2.0.50727 всегда будет установлена ​​даже после дальнейших обновлений .NET? Указатели на документацию Microsoft приветствуются.


person ephemient    schedule 15.10.2008    source источник


Ответы (6)


Шансы на то, что между версиями фреймворка будут меняться, невысоки (но не равны нулю!). Предполагается, что вы должны иметь возможность использовать двоичную сериализацию и удаленное взаимодействие для связи между клиентом и сервером, на котором работают разные версии фреймворка. Несовместимость между .NET 1.x и 2.0 является ошибкой, для которого доступен патч.

Однако у двоичной сериализации есть другие проблемы, особенно плохая поддержка управления версиями структуры, которую вы сериализуете. Из описанного вами варианта использования очевидным выбором является сериализация Xml: DataContractSerializer более гибкий, чем XmlSerializer, если вы не возражаете против зависимости от .NET 3.x.

Вы не можете гарантировать, что .NET framework 2.0 всегда будет установлен в будущих версиях Windows. Но я уверен, что Microsoft приложит все усилия, чтобы большинство приложений .NET 2.0 работали без изменений на .NET 4.x и более поздних версиях. У меня нет никаких ссылок на это: любое такое обязательство в любом случае действительно применимо только к следующей версии Windows (Windows 7).

person Joe    schedule 15.10.2008
comment
Я согласен с большей частью этого, но я не вижу смысла Windows 7 ... Я не очень много знаю ни о .NET 4.x, ни о Windows 7, но я бы ожидал, что .NET 4.x будет Vista и / вероятно / XP совместимы. Конечно, я могу быть невежественным ;-p - person Marc Gravell; 15.10.2008
comment
Я имел в виду, что, хотя Microsoft может взять на себя обязательство поставлять вместе с Windows 7 как .NET 2.0-3.5, так и .NET 4.0, сегодня они вряд ли возьмут на себя обязательства относительно того, какие версии фреймворка будут поставляться с более поздними версиями Windows. - person Joe; 15.10.2008

Как правило, эмпирическое правило таково: сериализация XML должна выдерживать новые версии фреймворка и, следовательно, может храниться в течение длительного времени, но двоичная сериализация не может (и, следовательно, всегда должна быть временной).

person Brad Wilson    schedule 15.10.2008
comment
Чтобы понять это; BinaryFormatter и т. Д. / Может / иметь проблемы ... существуют двоичные форматы, ориентированные на данные, а не на типы, и для этой цели их можно рассматривать как сродни плотному xml. protobuf-net является одним из них ;-p - person Marc Gravell; 15.10.2008

Какой сериализатор вы используете? Во многих отношениях сериализатор, такой как XmlSerializer или DataContractSerializer, буферизует вас от многих деталей и предоставляет более простые параметры расширяемости. В какой-то момент, несомненно, потребуется новая версия CLR - поэтому я не думаю, что кто-то может дать какие-либо гарантии относительно 2.0.50727; Однако в краткосрочной перспективе вы должны быть в безопасности. И я бы надеялся на меньшее количество критических изменений ...

[обновлено после примечания к другому ответу]

Если вам нужен двоичный формат из соображений экономии места / производительности, другой вариант - использовать другой двоичный сериализатор. Например, protobuf-net работает со всеми вариантами .NET *, но двоичный формат (разработанный Google) кроссплатформенный (Java, C ++ и т. д.), что делает его очень портативным, быстрым и компактным.

* = Я не пробовал это на микро-фреймворке, но поддерживаются CF, Silverlight, Mono, .NET 2.0 и т. Д.

person Marc Gravell    schedule 15.10.2008

Если совместимость вызывает беспокойство, ISerializable интерфейс может быть лекарством, которое вы ищете. Этот интерфейс дает вам больше контроля над сериализацией элементов. Для получения дополнительной информации попробуйте эту статью о msdn.

person Martin Clarke    schedule 15.10.2008

К остальным ответам у меня есть две вещи ...

Во-первых, используя настраиваемый SerializationBinder может решить множество проблем при импорте устаревших сериализованных данных.

Во-вторых, я считаю обязательным писать обширные модульные тесты для любых сохраняемых данных. В частности, я всегда делаю два теста:

  1. Тест туда и обратно - можете ли вы сериализовать и десериализовать свои объекты и получить обратно то же самое?
  2. Устаревший тест импорта - убедитесь, что у вас есть версии сериализованных данных, экспортированных из каждой выпущенной версии вашего приложения. Импортируйте данные и убедитесь, что все возвращается, как ожидалось.
person Mark Heath    schedule 15.10.2008

Вам не нужно использовать XML, чтобы получить более высокую гибкость и управление версиями.

Я использовал библиотеку с открытым исходным кодом Саймона Хьюитта, см. Оптимизация Сериализация в .NET - часть 2 вместо сериализации .NET по умолчанию. Он предлагает некоторую автоматизацию, но по сути вы можете контролировать поток информации, который сериализуется и десериализуется. Для управления версиями сначала может быть сериализована (файловая) версия, а во время десериализации способ интерпретации потока информации зависит от версии.

Это довольно просто сделать, хотя и несколько утомительно из-за явной сериализации / десериализации.

В качестве бонуса он в 20-40 раз быстрее и занимает меньше места для больших наборов данных (но может быть неважным в вашем случае).

person Peter Mortensen    schedule 10.09.2009