用于反序列化.NET中已更改的类的策略

时间:2012-04-19 22:42:24

标签: c# .net serialization

我有这个班级

[Serializable]
public class myClass() : ISerializable
{
    public int a;
    public int b;
    public int c;

    public void GetObjectData(SerializationInfo info, 
                              StreamingContext context)
        {
        // Some code
        }

    public myClass(SerializationInfo info, 
                   StreamingContext context)
        {
        // Some code
        }
}

我的数据库中有数百个这样的对象。我现在准备发布我的应用程序的新版本,其中该类已变为

[Serializable]
public class myClass() : ISerializable
{
    public int a;
    public string b;
    public int c;
    public bool d;

    public void GetObjectData(SerializationInfo info, 
                              StreamingContext context)
        {
        // Some code
        }

    public myClass(SerializationInfo info, 
                   StreamingContext context)
        {
        // Some code
        }
}

如何使用第二个版本的反序列化构造函数对基于第一个版本序列化的对象进行反序列化。

是否还有未来版本校对我的第二版课程的策略?

2 个答案:

答案 0 :(得分:4)

如果您没有做好准备,您可能需要诉诸黑客:当您的public myClass反序列化构造函数获得bool d的值时,请将代码括在try / {{1当您捕获异常时,将catch设置为其默认值。

将来添加dint(或任何其他名称不会与您传递给"__ver"的参数发生冲突),并将其设置为常量在类中维护以指示序列化中的兼容和不兼容的更改:

info.AddValue

答案 1 :(得分:2)

Serializable类非常适合通过相同版本的软件传递它们,但是在使用它来实现持久性时,您可以快速解决这个问题。如果您要将对象存储为BLOBs,那么可以使用类似protobuf-net的内容,允许通过允许可选字段进行序列化版本控制。

考虑到你目前的困境,所有你可以做的就是让它工作imediatly尝试捕捉新的字段,然后默认他们,如果他们不在那里:

protected myClass(SerializationInfo info, StreamingContext context)
{
    c = info.GetInt32("Value_C"); 
    try
    {
        b = info.GetBoolean("Value_B");
    }
    catch (SerializationException)
    {
        b = true;
    }
}