检测Serializable类是否已重命名字段/属性

时间:2018-04-06 14:32:18

标签: c# .net serialization

如果您有[可序列化]类,则会进行一些更改,例如重新命名属性或字段可能意味着在新版本中反序列化时会丢失数据。

我正在寻找一种自动检测这些变化的方法,以便手动检查所发生的事情。所以可以给两个.Net程序集,在其中找到Serializable类并检测可能发生的重大变化。

如果它可以忽略通常不是问题的事情,例如添加字段/属性,这是一个奖励,但不是必需的。

这种重构的一个例子适用于非可序列化的类,但会导致可序列化的重大问题:

// version 1

[Serializable]
class A 
{
    private string _name;
    public string Name 
    { 
       get { return _name;} 
       set {_name = value;}
    }
}

// version 2

[Serializable]
class A 
{
    public string Name { get; set;}
}

我喜欢这里的一种工具,它说的是

Class A - missing field _name
Class A - new property Name

到目前为止我考虑过的事情:

  • 使用[Serializable]属性查找所有类,创建实例并对其进行序列化。
    • 除了没有默认构造函数的问题之外,当第一次创建字段/属性为空时,感觉就像这样会很困难。
  • 使用反射在每个[Serializable]类中查找字段及其类型,并生成按字母顺序排列的列表。
    • 无法处理自定义序列化,感觉方法错误

(如果序列化程序本身很重要 - 我们目前使用自己的基于json的序列化程序,它继承自System.Runtime.Serialization.Formatter,所以它的行为与BinarySerializer的行为相同)

(编辑) Check whether binary serialized data matches the class which serialized it是一个类似的问题 - 似乎还没有一个简单的答案

1 个答案:

答案 0 :(得分:0)

如果有人在分割之前删除了检查值为0的字符串怎么办?我们用UnitTest测试它。

那么为什么不使用相同的方法呢?您可以只测试它或创建一些工具来收集参考数据。该工具为所有Seri​​alizable对象创建xml输出文件。也许添加一些时间戳,等等。这样的事情:

<ObjectName Timestamp="{CreatedDate}">
  <Field Type="int" Name="Id" />
  <Field Type="string" Name="Address" />
</ObjectName>
...

然后UnitTest使用此文件通过Reflection验证程序集。有了这些信息,我们就可以检测到字段,删除字段和新字段的变化。