9

私が理解しているように、この新しいメンバーがない古いバージョンのクラスを逆シリアル化するときは、新しいバージョンのクラスの新しいメンバーを[OptionalField]属性で装飾する必要があります。

ただし、クラスのシリアル化後にInnerTranslatorプロパティが追加されている間は、以下のコードは例外をスローしません。onDeserializationメソッド(シリアル化されていないことを確認する)でプロパティがnullであることを確認しましたが、そのためにコードが例外をスローすることを期待していました。[OptionalField]属性自体はオプションですか?

class Program
{
    static void Main(string[] args)
    {
        var listcol = new SortedList<string,string>
        {
            {"Estados Unidos", "United States"},
            {"Canadá", "Canada"},
            {"España", "Spain"}
        };
        var translator = new CountryTranslator(listcol);
        using (var file_stream=new FileStream("translator.bin",FileMode.Open))
        {
            var formatter = new BinaryFormatter();
            translator = formatter.Deserialize(file_stream) as CountryTranslator;
            file_stream.Close();
        }
        Console.ReadLine();
    }
}

[Serializable]
internal class CountryTranslator:IDeserializationCallback
{
    public int Count { get; set; }

    public CountryTranslator(SortedList<string,string> sorted_list)
    {
        this.country_list = sorted_list;
        inner_translator = new List<string> {"one", "two"};
    }
    //[OptionalField]
    private List<string> inner_translator;
    public List<string> InnerTranslator
    {
        get { return inner_translator; }
        set { inner_translator = value; }
    }

    private SortedList<string, string> country_list;

    public void OnDeserialization(object sender)
    {
        Debug.Assert(inner_translator == null);
        Count=country_list.Count;
    }
}
4

1 に答える 1

9

BinaryFormatter最良の場合、物事を変えると非常に壊れやすくなります。特に、自動的に実装されたプロパティ、難読化、名前の変更、厳密な名前付けなどには大きな問題があります。

私が覚えているように、[OptionalField]それがリリースされる直前に変更されたルールのいくつか。バージョントレラントなものは、計画されていたほど簡単には機能しなかったと思います。

私のアドバイス:バージョントレラントなシリアル化が必要な場合(つまり、今日シリアル化して、アプリの次のバージョンで逆シリアル化できる場合)、;を使用しないでくださいBinaryFormatterこれは(IMO)同じバージョン間でデータを渡す場合にのみ適しています(リモーティング、AppDomainsなど)。

バージョン間の作業には、コントラクトベースのシリアル化をお勧めします。XmlSerializerand DataContractSerializer(.NET 3.0)のようなもの、またはバイナリの場合-protobuf-netまたは同様のツール。これらはすべて、バージョンの許容範囲ではるかに優れています(実際、同じものに逆シリアル化する必要はありませんType)。さらに、プラットフォーム間で使用できるため、.NETでシリアル化し、java / C ++/etcで逆シリアル化できます。

于 2009-05-30T17:14:39.157 に答える