我正在开发的一个项目需要在关闭之前序列化数据结构,并在再次启动时从该序列化数据恢复其状态。

去年,我们正在构建 .NET 1.1,并遇到了一个棘手的问题:

  • 我们的代码在 .NET 2.0 上运行
  • 客户升级了某些软件,并以某种方式将 1.1 设置为默认值
  • 我们的代码在 .NET 1.1 上运行,无法反序列化其存储的状态

这个特定的问题已通过禁止特定的软件升级而“解决”,并且现在不应该成为问题,因为我们的目标是 .NET 2.0 框架(因此我们不可能在 1.1 上运行)。

这种序列化在 2.0 和更新的框架之间再次发生不兼容变化的可能性有多大?如果我们使用 <supportedVersion> 要将我们的代码修复为 2.0.50727,2.0.50727.1434 和 2.0.50727.nnnn(未来的某个版本)之间发生更改的可能性有多大?被序列化的数据结构是来自标准类库的数组、映射、字符串等。

此外,即使在进一步升级 .NET 后,是否也能保证始终安装 2.0.50727 框架?欢迎指向 Microsoft 文档。

有帮助吗?

解决方案

框架版本之间发生变化的可能性很低(但不是零!)。目的是您应该能够使用二进制序列化和远程处理在运行不同框架版本的客户端和服务器之间进行通信。.NET 1.x 和 2.0 之间的不兼容性 是一个错误 有可用的补丁。

然而,二进制序列化还有其他问题,特别是对正在序列化的结构的版本控制的支持很差。从您描述的用例来看,Xml 序列化是显而易见的选择:如果您不介意对 .NET 3.x 的依赖,DataContractSerializer 比 XmlSerializer 更灵活。

您无法保证 .NET Framework 2.0 将始终安装在未来版本的 Windows 上。但我确信 Microsoft 将努力确保大多数 .NET 2.0 应用程序在 .NET 4.x 及更高版本上运行不变。我对此没有任何参考:任何此类承诺在任何情况下都仅真正适用于下一版本的 Windows (Windows 7)。

其他提示

经验法则通常是:XML 序列化应该能够在新的框架版本中生存,因此可以长期存储,但二进制序列化不能(因此应该只是暂时的)。

您使用什么序列化器?在许多方面,像 XmlSerializer 或 DataContractSerializer 这样的序列化器可以缓冲许多细节,并提供更简单的可扩展性选项。在某些时候,新的 CLR 版本无疑是必要的 - 所以我认为没有人可以对 2.0.50727 做出任何保证;不过,短期内你应该是安全的。我希望更少的破坏性改变......

[更新了另一条回复的注释]

如果出于空间/性能原因需要二进制格式,那么另一种选择是使用不同的二进制序列化器。例如, protobuf网络 适用于所有 .NET 变体*,但二进制格式(由 Google 设计)是跨平台兼容的(Java、C++ 等)——使其非常便携、快速且小巧。

*=我还没有在微框架上尝试过,但是CF、Silverlight、Mono、.NET 2.0等都支持。

如果兼容性是一个问题, 可序列化 界面可能是您正在寻找的解决方案。此界面使您可以更好地控制项目的序列化方式。欲了解更多信息,请尝试这个 msdn 上的文章.

我有两件事要添加到其他答案......

首先,使用自定义 序列化绑定器 可以帮助您解决导入遗留序列化数据的许多困难。

其次,我认为有必要写大量的内容 单元测试 对于任何持久数据。我总是特别做两个测试:

  1. 往返测试——你能序列化和反序列化你的对象并得到完全相同的东西吗?
  2. 旧版导入测试 - 确保您拥有从应用程序的每个发布版本导出的序列化数据版本。导入数据并检查一切是否按预期返回。

您不必使用 XML 即可获得更高的灵活性和版本控制。

我用过Simon Hewitt的开源库,参见 优化 .NET 中的序列化 - 第 2 部分 而不是默认的 .NET 序列化。它提供了一些自动化功能,但本质上您可以控制序列化和反序列化的信息流。对于版本控制,(文件)版本可以先序列化,然后在 反序列化时,信息流的解释方式取决于版本。

虽然有些繁琐,但操作起来非常简单。 序列化/反序列化。

作为奖励,它的速度提高了 20-40 倍,并且对于大型数据集占用的空间更少(但对于您的情况可能并不重要)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top