2009-05-30 18 views
7

私が理解しているように、この新しいメンバを持たないクラスの古いバージョンを逆シリアル化すると、[OptionalField]属性を持つ新しいクラスのクラスに新しいメンバを飾る必要があります。[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; 
    } 
} 
+0

inner_translatorが[OptionalField]属性で装飾されていないとSOAPフォーマッタが例外をスローすることがわかりました – Dabblernl

答えて

8

BinaryFormatterあなたは物事を変更した場合、時間の最高で、非常に脆いです。特に、automatically implemented properties, obfuscactionには大きな問題があり、名前の変更、厳密な名前付けなどはありません。

私が思い起こせば、リリースされる直前には[OptionalField]の規則の一部が変更されました。バージョン・トレラントなものは、計画通り簡単にはうまくいかなかったと思う。

私のアドバイス:バージョン寛容なシリアル化(今すぐシリアル化し、次のバージョンのアプリケーションでデシリアライズすることができます)の場合はBinaryFormatterを使用しないでください。これは、同じバージョン(remoting、AppDomainなど)の間でデータを渡すためにのみ適しています(IMO)。

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

+0

正確には私が探していた答えではありませんでしたが、DataContractSerializerをあなたはこの投稿にそれを納得させました。結局、ありがとうございます;-) – Dabblernl

+0

ブール値や整数などの値の型に[OptionalField]を使用しますか?または、この属性は、OPの質問のような参照型にのみ関連していますか? –

関連する問題