【问题标题】:Check whether binary serialized data matches the class which serialized it检查二进制序列化数据是否与序列化它的类匹配
【发布时间】:2014-10-22 15:05:23
【问题描述】:

标题几乎说出了我想知道的内容。我有二进制序列化的数据,现在我再次读取它(类名保持不变),我想知道序列化程序是否遗漏了什么,例如,可能已重命名私有支持字段。

我做了以下重构:

private string descriptionField;
public string Description
{
  get { return this.descriptionField; }
}

public string Description { get; private set; }

正如in this article 中所述,这是行不通的。但是我真的很想知道是否有办法检测类是否与序列化数据不匹配。

我不想通过实现ISerializable 自己进行序列化,因为该类及其属性非常大并且可能会被更改。我更喜欢更简单的解决方案 =)

【问题讨论】:

  • 捕获它会抛出的异常,但您不能对尚未序列化的字段执行任何操作(只需提供有意义的默认值)。当然,如果您实施ISerializable,您将对此有更大的控制权(您知道您在阅读什么:如果一个字段没有被存储,那么它将不会被初始化,只需在每次读取之前检查)。
  • 问题是,它不会抛出异常,改变的字段名只是用它的默认值初始化
  • 如果你 rename 某些东西,那么它会抛出,因为找不到旧的变量名。如果你 add 什么都不会发生。在这种情况下,它们将只有默认值。在这里你可以做一些实现 ISerializable 的事情。在构造函数中,您将手动读取字段,您可以检查它们是否在序列化数据中可用。如果不是,您没有阅读它们,但您也知道它(这也是管理版本控制的一种非常原始的方式)。
  • 正如我所说,我提供的示例不会引发异常。隐式重命名是因为后台字段将由编译器在后台生成(我使用了BinaryFormatter)。我也不想使用ISerializable,因为班级很大
  • 想想OptionalFieldAttribute!它的存在是因为BinaryFormatter 可能 在这种情况下抛出。这不是它的默认行为,启用它将BinaryFormatter.AssemblyFormat 设置为FormatterAssemblyStyle.Full。也就是说,这不是管理这些东西的正确方法...ISerializable 是,即使写起来很烦人(嗯,BinaryFormatter - 但一般来说序列化 - 不是正确的选择跨版本保留应用程序数据,除非您正在做一些非常琐碎的事情)。

标签: c# serialization binary-serialization


【解决方案1】:

但是我真的很想知道有没有办法检测类是否与序列化数据不匹配?

检测它的一种方法是使用与先前序列化文件中相同的数据序列化现有类,然后比较先前和当前序列化文件的数字指纹。

我不想自己通过实现 ISerializable 来进行序列化,因为该类及其属性非常大并且可能会被更改。

由于您使用 BinaryFormatter 并处理潜在的重要版本问题,我认为您唯一的选择是实现 ISerializable 并自行处理反序列化,无论您喜欢与否。

【讨论】:

  • 我同意。反序列化器怎么可能知道你重命名了什么?最好的办法是自己动手。
  • 我想我会选择你的第一个选项。在我们的例子中,我们将序列化到硬盘驱动器的数据索引以保存服务器调用。因此,我们将对应用程序启动进行检查,这对于一个文件来说是可以的。谢谢=)
猜你喜欢
  • 2018-11-16
  • 1970-01-01
  • 2023-01-14
  • 2014-01-04
  • 2010-11-08
  • 2016-09-15
  • 1970-01-01
  • 2023-04-07
  • 2013-08-16
相关资源
最近更新 更多