【问题标题】:How to refactor a class that is serialized in .NET?如何重构在 .NET 中序列化的类?
【发布时间】:2011-04-02 12:18:02
【问题描述】:

我有一个由BinaryFormatter 序列化到磁盘的 C# 类,例如这个例子:

// 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;
}

稍后,我想通过以下一项或多项重构该类
- 更改名称
- 更改其命名空间
- 移动到另一个程序集

据我所知,只有在具有完全相同名称、命名空间和程序集名称的类可用时,才能对二进制文件进行反序列化。

我该如何解决这个问题?
是否可以在不破坏Version Tolerant Serialization 的情况下将反序列化映射到不同的类名、命名空间和程序集?

【问题讨论】:

    标签: .net serialization refactoring versioning binaryformatter


    【解决方案1】:

    您可以实现ISerializable 接口并覆盖GetObjectData 以提供您自己的反序列化。我没有尝试过,但您应该能够“手动”反序列化您的旧对象。

    【讨论】:

    • 所以你的意思是Person应该实现ISerializable和GetObjectData()?当具有不同的名称、命名空间和/或程序集时,反序列化程序如何知道应该使用这个确切的 Person 类?我可以告诉反序列化器使用哪个类吗?
    【解决方案2】:

    经过一些研究,我意识到 BinaryFormatter 确实支持我正在寻找的一切。

    BinaryFormatter 可以使用 代理

    1. 提供序列化最初未设计为序列化的类型的能力。
    2. 提供将一种类型的一个版本映射到另一种类型的另一个版本的方法。

    也可以使用 SerializationBinder 将反序列化从类型 A 映射到类型 B(不同的类名、命名空间和/或程序集名称)。

    据我所知,这使得重构序列化的类成为可能,并在进行单独版本控制不支持的重大更改时保持向后兼容性。

    参考:http://www.diranieh.com/NETSerialization/BinarySerialization.htm

    编辑:顺便说一句,重构字段(名称或类型)仍然很痛苦,正如Renaming fields then deserializing in C# 中所讨论的那样。我目前正在研究 protobuf-net,以便将来更好地解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多