2009-05-30 39 views
7

據我瞭解,我必須在我的類的新版本中用[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

我剛剛發現SOAP格式化程序在inner_translator沒有用[OptionalField]屬性 – Dabblernl 2009-05-30 16:02:56

回答

8

BinaryFormatter如果你改變的事情是,在時代的最,很脆。同樣重要的是,automatically implemented properties, obfuscaction存在很大的問題,重命名,強命名等。

我記得,有些關於[OptionalField]的規則在發佈之前發生了變化;我認爲,版本容忍的事情並沒有像計劃的那樣容易實現。我的建議:如果你想要版本寬容的序列化(即你今天可以序列化並且用你的應用程序的下一個版本進行反序列化),那麼請不要使用BinaryFormatter;這是(IMO)僅適用於在相同版本(遠程處理,AppDomain s等)之間傳遞數據。

對於版本之間的工作,我推薦基於合同的序列化;例如XmlSerializerDataContractSerializer(.NET 3.0),或者用於二進制 - protobuf-net或類似工具。所有這些都是更好的版本寬容(事實上,你甚至不需要反序列化到相同的Type);加上它們可以在平臺之間使用 - 所以你可以在.NET中序列化並在java/C++/etc中反序列化。

+0

裝飾時確實會拋出一個異常不是我正在尋找的答案,但是我發現我已經完全轉向使用DataContractSerializer,你在這篇文章中提到了它。所以,感謝所有;-) – Dabblernl 2009-09-06 08:16:02