6

私はこのクラスを持っています

[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 番目の逆シリアル化コンストラクターを使用してどのように逆シリアル化しますか。

クラスの 2 番目のバージョンを将来のバージョンで校正するための戦略はありますか?

4

2 に答える 2

4

あなたの側で準備をせずに、ハックに頼る必要があるかもしれません:public myClass逆シリアル化コンストラクターが の値を取得したらbool d、コードをtry/で囲み、例外をキャッチしたときにデフォルト値にcatch設定します。d

int将来的には、値"__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;
        }
    }
}
于 2012-04-19T23:00:28.310 に答える
2

シリアライズ可能なクラスは、同じバージョンのソフトウェアを介してそれらを渡すのに最適ですが、永続化のために使用するとすぐにこの問題が発生します。オブジェクトをBLOBとして保存する場合は、オプションのフィールドを許可することでシリアル化のバージョン管理を可能にするprotobuf-netなどを使用してください。

現在の苦境を考えると、すぐに機能させるためにできることは、新しいフィールドに try catch を配置し、そこにない場合はデフォルトにすることだけです。

protected myClass(SerializationInfo info, StreamingContext context)
{
    c = info.GetInt32("Value_C"); 
    try
    {
        b = info.GetBoolean("Value_B");
    }
    catch (SerializationException)
    {
        b = true;
    }
}
于 2012-04-19T23:23:59.527 に答える