如何重构.NET中序列化的类?

发布于 2024-09-15 12:55:41 字数 780 浏览 12 评论 0原文

我有一个由 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;
}

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

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

我该如何解决这个问题?
是否可以将反序列化映射到不同的类名、命名空间和程序集而不破坏 版本容忍序列化

I have a C# class that is serialized to disk by the BinaryFormatter, such as this example:

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

Later, I want to refactor this class by one or more of the following
- Change its name
- Change its namespace
- Move to another assembly

As far as I can tell, the binary file can only be de-serialized if a class with the exact same name, namespace and assembly name is available.

How do I work around this?
Is it possible to map the de-serialization to a different class name, namespace and assembly without breaking Version Tolerant Serialization?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

年少掌心 2024-09-22 12:55:41

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

BinaryFormatter 可以使用代理来

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

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

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

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

编辑:顺便说一句,重构字段(名称或类型)仍然很痛苦,如 在 C# 中重命名字段然后反序列化。我目前正在研究 protobuf-net 以在将来更好地解决这个问题。

After some research I realized that the BinaryFormatter does support everything I was looking for.

A BinaryFormatter can use surrogates to

  1. Provides the ability to serialize a type that was not originally designed to be serialized.
  2. Provides a way to map one version of a type to another version of another type.

One can also map deserialization from type A to type B (different class name, namespace and/or assembly name) by using SerializationBinder.

As far as I can tell, this makes it possible to refactor classes that are serialized and to maintain backwards compatibility when making breaking changes that is not supported by versioning alone.

Reference: http://www.diranieh.com/NETSerialization/BinarySerialization.htm

Edit: On a side note, refactoring fields (name or type) is still a pain, as discussed in Renaming fields then deserializing in C#. I am currently looking into protobuf-net to better solve this in the future.

反话 2024-09-22 12:55:41

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

You can implement the ISerializable interface and override GetObjectData to provide your own deserialization. I have not tried, but you should be able to deserialize your old object "manually".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文