2009-06-02 94 views
6

我有数据存储在一个类的实例已被序列化.net BinaryFormatter。我现在想要重命名类中的某个字段,但仍然能够反序列化旧数据。重命名字段,然后反序列化在C#中

一个选项是手动实现ISerializable并反序列化类的所有字段。但是,这看起来像很多工作,特别是如果我的课有很多领域,我只重新命名了一个领域。

有没有更好的方法?


Craig建议保留旧类的反序列化副本,并将值复制到新类中。我在其他地方也看到了这一点 - 这对于实现ISerializable有什么优势?据我所见,复制这个类给我留下了两个几乎完全相同的类的副本,并且我仍然必须将所有旧类的值复制到新类中 - 这看起来与实现ISerializable具有相同的工作量几乎重复类混入。


两个答案都提到了Binders。我已经成功地使用SerializationBinder来反序列化一个被序列化为类Foo的类Bar,但那是因为类的名称改变了。当你重命名一个字段时,SerializationBinder是否也有帮助 - 例如,当int m_Left被重命名为int m_Right时?

+0

在Binder的BindToType方法中,当您获得带有目标类型(类)的typeName字符串时,只需返回更改属性的新类型即可。类已经改变了属性,但现在是不同的类型。没有办法只适用于一个物业。 – 2009-06-02 23:23:14

回答

2

你可以尝试让老过去的唯一目的是补液,然后只需复制你需要的字段到新的类。仍然有点痛苦,但应该工作。

1

是的,这是现场串行器的问题。您可以使用自定义Binder或“序列化代理”来避免实施ISerializable,但这只是个案修复。

我已经讨论了这个主题(在混淆器和自动道具的背景下)here。我的建议是:不要使用BinaryFormatter的版本之间的数据......为的持久性,看看基于合同的串行:

  • XmlSerializer
  • DataContractSerializer
  • 或二进制,像protobuf-net

这些都不能帮助您今天,但它可能会帮助您在将来设计它。

0

如果您只是将该属性的访问修饰符更改为私有属性,然后拥有基本上包装旧属性的新名称的公共属性会怎样。这样,你仍然应该能够反序列化(我想),但使用这个类的人不会知道旧名称。只是一个想法...

+0

这将工作,如果序列化作用于属性,但据我所知,它直接与私人领域工作......(如果我在记事本中打开文件,我看到像m_Foo和m_Bar字段名称,而是属性名称如Foo和Bar ... – 2009-06-03 08:47:10