Может извлечь базовый класс сломать двоичную сериализацию - PullRequest
0 голосов
/ 26 октября 2018

Если у меня есть класс с несколькими полями, и я сериализую его, используя двоичную сериализацию.

Затем я извлекаю базовый класс и перемещаю некоторые поля из класса в базовый класс.Например,

class Class
{
     int field1;
     string field2;
}

Изменено на

class Class : BaseClass
{
     int field1;
}

class BaseClass
{
     string field2;
}

Возможно ли это как-то разбить сериализацию - то есть всегда ли удастся десериализовать старые версии Class в новые версиикласса и наоборот.

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

1 Ответ

0 голосов
/ 26 октября 2018

РЕДАКТИРОВАТЬ: При десериализации существует проблема: член "field1" не будет должным образом десериализован.

1) Серийный номер:

var person = new Employee()
            { 
                Name = "Mark Zuckerberg",
                Salary = 1000
            };

var bf = new BinaryFormatter();
bf.Serialize(new FileStream("C:\\TEMP\\test.dat", FileMode.Create), person);


[Serializable]
public class Employee
{
  public string Name { get; set; }
  public decimal Salary { get; set; }
}

2) Изменена структура класса

[Serializable]
public abstract class Person
{
  public string Name { get; set; }           
}

[Serializable]
public class Employee : Person
{            
  public decimal Salary { get; set; }
}

3) Десериализовано: имя равно нулю enter image description here


Оригинальный ответ:

Предполагается, что вы используете BinaryFormatter , В этой статье ничего об этом не упоминается, поэтому я догадываюсь все в порядке ( РЕДАКТИРОВАТЬ: Это НЕштраф ).

Вот некоторые рекомендации, которым необходимо следовать в целом (также извлечено из статьи выше):

  • Никогда не удаляйте сериализованное поле.
  • Никогдаприменять атрибут NonSerializedAttribute к полю, если атрибут не был применен к полю в предыдущей версии.
  • Никогда не меняйте имя или тип сериализованного поля.
  • При добавлении нового сериализованного поляпримените атрибут OptionalFieldAttribute.
  • При удалении NonSerАтрибут ializedAttribute из поля (который не был сериализуем в предыдущей версии), примените атрибут OptionalFieldAttribute.
  • Для всех необязательных полей установите значимые значения по умолчанию, используя обратные вызовы сериализации, если только 0 или ноль в качестве значений по умолчанию приемлемы.

Чтобы обеспечить совместимость типа с будущими механизмами сериализации, выполните следующие действия.эти рекомендации:

  • Всегда правильно устанавливайте свойство VersionAdded в атрибуте OptionalFieldAttribute.
  • Избегайте разветвленного управления версиями.
...