2010-05-05 70 views
0

我正在序列化一个对象并将序列化的值存储在数据库中,并且在从数据库获取值之后也使得反序列化工作正常。反序列化时对象发生了变化

但是,如果现有对象被修改并且在该类中添加了新属性,则会出现问题。然后,当反序列化它在序列化文本中查找该属性,并且在其中未找到该属性时,出现以下错误

System.Runtime.Serialization.SerializationException:找不到成员'temp'。

有没有什么办法可以知道新的属性是否存在序列化时可以跳过?我正在使用自定义序列化。

回答

1

这是一个常见问题,当保湿/保湿实例和改变基础类型的同时。

在这种情况下你可以做的事情是将头文件的等价物与可用于反序列化的属性信息一起写出,以便您可以知道哪些字段实际上是序列化的。你“标签”的每个字段,完全取决于你的方式,我在这里要做到这一点只是为了演示的目的最简单的方式:

public virtual void GetObjectData(SerializationInfo info, StreamingContext context) 
{ 
    info.AddValue("_Fields", 2); 
    info.AddValue("FieldA", FieldA); 
    info.AddValue("FieldB", FieldB); 
} 

protected MyObject(SerializationInfo info, StreamingContext context) 
{ 
    int fields = 0; 
    try{ 
    fields = info.GetInt32("_Fields"); 
    }  
    catch(Exception) 
    { 
    /* min known version kicks in instead, i.e. 
     before you added this field-tracking value */ 
    } 

    if(fields!=0) 
    { 
    //if using an integer tracking field, you could also consider using 
    //bit flags - changing these tests to (fields & [fieldFlag]) == [fieldFlag] 
    //which would allow you to accommodate multiple combinations of fields more easily. 
    if(fields == 1) 
     FieldA = info.GetInt32("FieldA"); 
    if(fields == 2) 
     FieldB = info.GetInt32("FieldB"); 
    } 
} 

正如代码所暗示的,当你转出此更改,您应该对数据存储中对象数据的当前最高级别详细信息有很好的了解,因此您仍然可以反序列化所有不执行此操作的内容。

您可以更进一步并使用字符串来跟踪存在的数据,使每个字符串与存储的字段的名称相同,然后使用一些基于反射的解决方案来自动填充字段。尽管这可能是难看的代码(或者,至少我现在没有足够的时间来提供示例!)。

+0

当然 - 我使用位标志的建议取决于事实,即永远不会超过32或64(如果使用较长的)字段进行序列化! – 2010-05-05 15:05:09

1

尝试XmlSerializer。它是版本宽容的。