4

を使用してデータをシリアル化するアプリケーションがありますBinaryFormatter。クラス名を変更せずに、あるバージョンから次のバージョンにシリアル化されたクラスにメンバーが追加されました。古いシリアル化されたファイルに追加されたメンバーが存在しない可能性を処理するためのコードが追加されました。

private void readData(FileStream fs, SymmetricAlgorithm dataKey)
{
    CryptoStream cs = null;

    try
    {
        cs = new CryptoStream(fs, dataKey.CreateDecryptor(),
            CryptoStreamMode.Read);
        BinaryFormatter bf = new BinaryFormatter();

        string string1 = (string)bf.Deserialize(cs);
        // do stuff with string1

        bool bool1 = (bool)bf.Deserialize(cs);
        // do stuff with bool1

        ushort ushort1 = (ushort)bf.Deserialize(cs);
        // do stuff with ushort1

        // etc. etc. ...

        // this field was added later, so it may not be present
        // in the serialized binary data.  Check for it, and if
        // it's not there, do some default behavior

        NewStuffIncludedRecently newStuff = null;

        try
        {
            newStuff = (NewStuffIncludedRecently)bf.Deserialize(cs);
        }
        catch
        {
            newStuff = null;
        }

        _newStuff = newStuff != null ?
                new NewStuffIncludedRecently(newStuff) :
                new NewStuffIncludedRecently();
    }
    catch (Exception e)
    {
        // ...
    }
    finally
    {
        // ...
    }
}

私が今しているポイントは、本当にすすぎ、追加したい別のメンバーで繰り返したいということです。つまり、別のフィールドを追加して、と同様のブロックを試してみNewStuffIncludedRecentlyます。

クラス全体を作成することを考えていました[Serializable]が、古いシリアル化されたデータとの互換性が損なわれることはありませんか?

私の主な懸念は、逆シリアル化がどのように機能するかが明確でないことです。上記と同様に別のオプションフィールドの処理を追加すると、機能しますか?これらの変更をより適切に処理するために私が持っている他のオプションは何ですか?

いつものように事前に感謝します。

4

1 に答える 1

3

新しいフィールドにマークを付けると機能[OptionalField]するはずですが、場合によってはフレークネスの報告を聞いています。BinaryFormatterを避けているので、はっきりとは言えません。バージョン管理時に非常に多くの問題があるためです:)(さらに、いくつかの選択肢ほど「タイト」ではなく、クロスプラットフォームに移行したい場合は深刻な問題があります、またはCF / SLなどに)

を実装ISerializableしている場合は、次のことを試してみてください。

foreach(SerializationEntry entry in info) {
    switch(entry.Name) {
         case "Name": Name = (string)info.Value;
         case "Id": Id = (int)info.Value;
         ...
    }
}

しかし、繰り返しになりますが、これは難しい方法です:pこのアプローチでは、実際にそこにあるデータのみを処理します。

于 2011-11-23T16:30:38.900 に答える