可以提取基数 class 破坏二进制序列化

Can extracting a base class break binary serialisation

如果我有一个包含多个字段的 class,我使用二进制序列化对其进行序列化。

然后我提取一个基数 class 并将一些字段从 class 移到基数 class 中。例如

class Class
{
     int field1;
     string field2;
}

改为

class Class : BaseClass
{
     int field1;
}

class BaseClass
{
     string field2;
}

这是否有可能以任何方式破坏序列化 - 即是否总是可以将旧版本的 Class 反序列化为新版本的 Class,反之亦然。

我进行的实验表明这很好,但如果有人知道这不起作用的任何边缘情况,那在我将其放入生产代码之前显然会很棒。

编辑: 反序列化时出现问题:成员 "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) 更改了 class 结构

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

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

3)反序列化:名称为空


原答案:

假设您使用的是 BinaryFormatter, this 文章没有提及任何相关内容,所以我 猜测 没问题(编辑:没问题).

以下是一般应遵循的一些最佳做法(也摘自上述文章):

  • 切勿删除序列化字段。
  • 切勿将 NonSerializedAttribute 属性应用于字段 属性未应用于先前版本中的字段。
  • 切勿更改序列化字段的名称或类型。
  • 添加新的序列化字段时,应用 OptionalFieldAttribute 属性。
  • 从字段中删除 NonSerializedAttribute 属性时(即 在以前的版本中不可序列化),应用 可选字段属性。
  • 对于所有可选字段,使用 序列化回调,除非 0 或 null 作为默认值是可以接受的。

为确保类型与未来的序列化引擎兼容,请遵循以下准则:

  • 始终在 OptionalFieldAttribute 上设置 VersionAdded 属性 属性正确。
  • 避免分支版本控制。