【问题标题】:Ignore obsolete field when deserializing反序列化时忽略过时的字段
【发布时间】:2014-08-03 19:39:59
【问题描述】:

我整天都在寻找一种方法来实现这一目标而没有结果......

我正在尝试反序列化一个对象。当我对其进行序列化时,我有一个名为(比如说)obsoleteBool 的 bool。在新版本的类中,我删除了这个 bool,现在反序列化时出现错误(未找到字段“obsoleteBool”)。

在新旧版本的类之间添加新字段非常容易。即使不使用 [OptionalField] 属性...但是如何管理在新旧版本的类之间删除字段?

【问题讨论】:

  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • 实现 ISerializable。这需要时间和精力,但您将拥有更多控制权(并且您可以 - 粗略地 - 管理版本控制)。
  • 你用什么序列化它?
  • 我希望我的课程被用户扩展。据我了解,使用 ISerializable 将要求他们管理他们将创建的新变量的序列化。当我使用 [Serializable] 属性时,他们可以创建新变量而无需执行任何其他操作来保存它。 @ahruss:我正在使用 BinaryFormatter 进行序列化

标签: c# serialization field versioning obsolete


【解决方案1】:

有 3 种可能的解决方案:

  • 最简单的:将旧字段添加到新版本的类中
  • 自定义代码:实现自定义反序列化器
  • 额外工作:编写一个转换程序,遍历所有序列化的类,使用旧格式读取它们并使用新的类定义重新序列化它们。

就商业价值而言,第一个选项可能更可取。

【讨论】:

  • 因为用户将扩展我的类并且可能会在序列化之间进行大量迭代,所以我希望尽可能地使用最简洁的解决方案。保留过时的字段可能很快就会导致代码非常混乱,甚至没有谈论可能因此选择不重命名变量并最终导致名称不合适或类似问题的人。自定义序列化程序是否能够自动考虑用户创建的新字段?关于转换程序,如果我尝试时出现“缺少字段”错误消息,我什至能够打开要转换的类?
  • @RyanPergent 和 ISerializable 你也可以管理派生类中的字段(就像 BinaryFormatter 一样)。当然这不是最好的解决方案,但你可以做到(通过反射)。要进行转换,您必须部署两个版本(有和没有额外字段),在一个 AppDomain 中反序列化,在第二个 AppDomain 中将反序列化的数据移动到新格式。相当困难。 IMO 的重点是序列化不是用于数据文件的工具(带有版本控制)。它对很多事情都有用,但不是这个(因为在几个版本之后它会让你的代码变得混乱,如果你改变层次结构......)
  • 我现在正在尝试实现 ISerializable 方法。唯一的不便是我需要在所有继承自默认类的类中都有一个带有 SerializationInfo 和 StreamingContext 的构造函数(我有很多)。但与无法删除变量相比,这是一个小缺陷。但是,我面临另一个问题:我正在使用反射来获取和保存所有字段,但我只需要获取 [Serializable] 字段。 BindingFlags 似乎没有提供这样的过滤...有人知道我如何以这种方式过滤我的字段吗?
  • 我设法使用来自 System.Reflection.FieldInfo 的 IsNotSerialized 过滤掉它们 :) 非常感谢你们的帮助,我想我现在可以实现我想要的了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 1970-01-01
  • 2016-07-26
相关资源
最近更新 更多