可以提取基数 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 属性
属性正确。
- 避免分支版本控制。
如果我有一个包含多个字段的 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 属性 属性正确。
- 避免分支版本控制。