Как провести рефакторинг класса, сериализованного в .NET? - PullRequest
7 голосов
/ 23 августа 2010

У меня есть класс C #, который сериализуется на диск с помощью BinaryFormatter , например, в следующем примере:

// Version 3.0
[Serializable]
public class Person
{
    public string FullName;

    [OptionalField(VersionAdded=2)]
    public string NickName;
    [OptionalField(VersionAdded=2)]
    public DateTime BirthDate;

    [OptionalField(VersionAdded=3)]
    public int Weight;
}

Позже я хочу реорганизовать этот класс одним или несколькими из следующих
- сменить название
- изменить свое пространство имен
- перейти к другой сборке

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

Как мне обойти это?
Можно ли сопоставить десериализацию с другим именем класса, пространством имен и сборкой без прерывания Версия Допустимая сериализация ?

Ответы [ 2 ]

5 голосов
/ 28 сентября 2010

После некоторых исследований я понял, что BinaryFormatter поддерживает все, что я искал.

BinaryFormatter может использовать суррогаты до

  1. Обеспечиваетвозможность сериализации типа, который изначально не был предназначен для сериализации.
  2. Предоставляет способ сопоставления одной версии типа другой версии другого типа.

Можно также сопоставить десериализацию от типа A к типу B (другое имя класса, пространство имен и / или имя сборки), используя SerializationBinder .

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

Ссылка: http://www.diranieh.com/NETSerialization/BinarySerialization.htm

Редактирование: На заметку сторон, рефакторинг полей (имя или тип) все еще является проблемой, как обсуждалось в Переименование полей, а затем десериализация в C # .В настоящее время я изучаю protobuf-net, чтобы лучше решить эту проблему в будущем.

1 голос
/ 23 августа 2010

Вы можете реализовать интерфейс ISerializable и переопределить GetObjectData, чтобы обеспечить собственную десериализацию.Я не пробовал, но вы должны быть в состоянии десериализовать ваш старый объект "вручную".

...