我在我的项目中使用 YamlDotNet 已经有一段时间了,不过随着其中一个项目的不断发展,我可以利用您的帮助来解决我面临的以下问题。
想象一下我已经序列化以下对象一段时间了(我会让一切尽可能简单):
[YamlSerializable]
public class Trip
{
[YamlMember]
public string Name { get; set; }
[YamlMember]
public int[] BreakTimestamps { get; set; }
}
BreakTimestamps
是从行程开始算起的时间戳(以秒为单位)。
现在,假设我为过去几年的旅行收集了相当多的序列化对象(在文件中)。
我的项目不断发展,我想收集更多有关旅行的信息,因此我将我的
Trip
课程更新为以下内容:
[YamlSerializable]
public class Trip
{
[Flags]
public enum BreakType
{
Undefined = 0,
Nutrition = 1 << 0,
Sanitary = 1 << 1,
Mechanical = 1 << 2,
Sightseeing = 1 << 3,
Other = 1 << (sizeof(int) - 1)
}
[YamlSerializable]
public class Break
{
[YamlMember]
public int Timestamp { get; set; }
[YamlMember]
public int Duration { get; set; }
[YamlMember]
public BreakType Reason { get; set; }
}
[YamlMember]
public string Name { get; set; }
[YamlMember]
public Break[] Breaks { get; set; }
}
我面临的问题是,如果我使用新类来反序列化现有文件,我将不会获得有关时间戳的任何信息。 我想要实现的是,如果我反序列化以前的版本,对于
BreakTimestamps
中的每个元素,我将创建一个新的 Break
对象并仅填充 Timestamp
属性,因此我将逐渐更新所有以前的版本对象。
您对如何解决这个问题有什么想法吗?
我看到以下可能性:
BreakTimestamps
属性以实现向后兼容性,但这会在每个新序列化的对象中创建冗余信息Trip_V2.0
,使用忽略不匹配属性的反序列化器 (var deserializer = (Deserializer)new DeserializerBuilder().IgnoreUnmatchedProperties().Build();
),检查版本并使用相应的目标进行反序列化(<Trip>
或 <Trip_V2.0>
)如有其他想法,我将不胜感激。 对于最优雅的解决方案,让我们假设这不是该对象类的最后一次更新,我希望有未来更新的可能性。
感谢您的任何建议。
当您的代码发生这样的重大更改时,您通常会对数据运行一次性升级,将旧格式转换为新格式。
如果您使用 YAML、某些其他文件格式或某种数据库,这也是一样的。