Тип объектов между сериализациями, учитывая изменения класса - PullRequest
3 голосов
/ 01 мая 2019

Я храню информацию, связанную с типом, в словаре, например,

Dictionary<Type, int> TypeInformation;

TypeInformation[typeof(OneOfMyOwnClasses)] = 42;

Затем я (двоичный файл) сериализую состояние моего приложения, включая приведенный выше словарь.

Что произойдет с объектами типа , если я изменю OneOfMyOwnClasses в коде ? При каких условиях объекты типа остаются неизменными после десериализации? То есть когда будет

if (TypeInformation[typeof(OneOfMyOwnClasses)] == 42)
    MessageBox.Show("Yahoo !!!");

дать положительный результат даже после десериализации состояния моего приложения?

  • Гарантируется ли смена тел методов между объектами одного типа?
  • Изменяет ли что-нибудь изменение имен закрытых методов или полей в объектах типа?
  • Изменения имен открытых методов (или полей)?
  • Изменение пространства имен или сборки?
  • Изменение самого имени класса? (предположительно нет ... ;-))

Наконец, учитывая все это, есть ли веские причины не сериализовать информацию о типах, и есть ли лучший, но более сложный способ (например, создание GUID и т. Д.)?

1 Ответ

1 голос
/ 01 мая 2019

Если вы имеете в виду BinaryFormatter, то:

  1. изменение типа, пространства имен или идентификатора сборки типа нарушит сериализатор, если вы храните экземпляры типа или сам объект Type
  2. изменение имен или типов полей для типа приведет к поломке сериализатора, , если вы храните экземпляров этого типа

В обоих случаях есть способы как-то исправить это, перепрыгивая через сложные обручи, но обычно попробовать не стоит. Исходя из моего опыта, BinaryFormatter просто не является хорошим выбором, за исключением очень специфических сценариев (в частности, RPC между двумя запущенными приложениями, которые по необходимости должны выполнять один и тот же код - такой как изоляция домена приложения), и если ваше намерение общего назначения хранилище , вам обычно лучше использовать что-нибудь еще . В частности, я склоняюсь к protobuf-net (который является «двоичным» в том смысле, что он реализует двоичный формат «буферов протокола») от Google, но я, по общему признанию, предвзят. JSON и XML также являются хорошими вариантами с точки зрения переносимости, хотя они почти всегда имеют больший выход и (немного) более медленную обработку.

Обратите внимание, что большинство сериализаторов при сериализации объекта Type будут использовать полное имя, поэтому пункт 1 выше будет применяться к большинству, хотя для каждого сериализатора способы меняются что может существовать. Честно говоря, я бы сказал, что если вы сериализуете Type экземпляр, вы делаете что-то не так , и было бы лучше сделать это как поиск с ручным ключом по отношению к некоторой внешней ссылке (который может быть через атрибут типа, например). Например:

[SomeMarker("abc")]
class OneOfMyOwnClasses {...}

затем используйте отражение, чтобы получить экземпляр SomeMarkerAttribute (в некотором кэшированном виде), так что вы на самом деле сохраните:

Type type = ...
string key = GetMarkerFromType(type); // "abc"
Dictionary<string, int> TypeInformation;
TypeInformation[key] = 42;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...