C# 反序列化.NET中已更改的类的策略

C# 反序列化.NET中已更改的类的策略,c#,.net,serialization,C#,.net,Serialization,我有这门课 [Serializable] public class myClass() : ISerializable { public int a; public int b; public int c; public void GetObjectData(SerializationInfo info, StreamingContext context) { // S

我有这门课

[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
        }
}
如何使用第二个版本的反序列化构造函数反序列化基于第一个版本序列化的对象


是否还有未来版本验证我的第二个版本的策略?

在没有准备的情况下,您可能需要求助于黑客:当您的
公共myClass
反序列化构造函数获得
bool d
的值时,将代码括在
try
/
catch
中,并在捕获异常时将
d
设置为其默认值

将来,添加一个
int
“\uu\u ver”
(或与传递给
info.AddValue
的参数不冲突的任何其他名称),并将其设置为您在类中维护的常量,以指示序列化中的兼容和不兼容更改:

public class myClass : ISerializable {
    private const int __ver = 4;
    public int a;
    public string b;
    public int c;
    public bool d;

    public void GetObjectData(SerializationInfo info, 
                          StreamingContext context) {
        info.AddValue("__ver", ver);
        info.AddValue("a", a);
        // and so on
    }

    public myClass(SerializationInfo info, 
               StreamingContext context) {
        switch(info.GetInt32("__ver")) {
            case 3: 
                // Deserialize prior version
            break;
            case 4: 
                // Deserialize current version
            break;
        }
    }
}

可序列化类非常适合在同一版本的软件中传递它们,但是在使用它进行持久化时,很快就会遇到这个问题。如果要将对象存储为,那么可以使用类似这样的方法,通过允许可选字段来实现序列化版本控制

考虑到您当前的困境,要使其立即工作,您所能做的就是在新字段周围放置一个try catch,如果没有,则默认为:

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

制作一个转换器程序,读取第一种类型的对象,生成第二种类型的对象,并用新对象替换旧对象。如果你说的是数百条而不是数百万条记录,那么运行这个程序应该需要很长时间。最好从这里开始:唯一的问题是数据库中的所有当前实例上都没有“版本”字段,因此您无法改装此实现。
SerializationInfo
没有类似于
ContainsKey()
?我认为这在这里非常有用。我认为您可以使用
MemberCount
GetEnumerator()
来避免
尝试
/
捕获
@PeteDavis正确-这是我答案第一段的主题。