2015-04-26 61 views
0

因爲XmlSerializer不會在字典上工作,所以我在它們上使用XmlIgnore屬性,並使用中介列表<>屬性將字典呈現爲列表,其中的作用是的工作與序列化。但是,我的List <>屬性在反序列化時被忽略。 (沒有引發錯誤,也沒有引發序列化事件。)爲什麼?C#xml反序列化忽略List <>屬性意外

[XmlIgnore] 
public Dictionary<string, string> ConnectionStrings { get; set; } 

這是應該用於de/serialization的「surrogate」列表屬性。就像我說的,這對序列化有效,但是在反序列化過程中該屬性被忽略。我試圖理解爲什麼/怎麼辦呢什麼....

public List<ConnectionItem> SerializedConnections 
{ 
    get 
    { 
     return ConnectionStrings.Select(keyPair => new ConnectionItem() { Name = keyPair.Key, ConnectionString = keyPair.Value }).ToList(); 
    } 
    set 
    { 
     ConnectionStrings = new Dictionary<string, string>(); 
     foreach (var ci in value) ConnectionStrings.Add(ci.Name, ci.ConnectionString); 
    } 
} 

我想在我的SerializedConnections屬性的set訪問設置一個斷點,但它從來沒有擊中。

+0

我不知道爲什麼Dictionary不可序列化,這並不難。您可以創建自己的SerializableDictionary類並實現IXmlSerializable來序列化數據。我已經做了幾次,但我沒有代碼方便分享。 –

回答

1

這永遠不會像你所假設的那樣工作。在反序列化過程中,XmlSerializer調用getter來檢索大概爲空的List<T>實例,然後調用它的Add(T item)方法以反序列化對象填充它。

documentation in MSDN,特別是說:

XmlSerializer的給予特殊處理,以實現IEnumerableICollection類。實現IEnumerable的類必須實現一個採用單個參數的公共Add方法。 Add方法的參數必須與從GetEnumerator返回的值的Current屬性或該類型的其中一個基值返回的屬性類型相同。除IEnumerable之外,執行ICollection(例如CollectionBase)的類必須具有一個公開的Item索引屬性(C#中的索引器),它具有一個整數,並且它必須具有一個公共類型爲Count的integer類型的屬性。 Add方法的參數必須與從Item屬性返回的類型相同,或者該類型的基礎之一。對於實現ICollection的類,要從序列化的Item屬性中檢索要序列化的值,而不是通過調用GetEnumerator

設計的核心問題是SerializedConnections屬性的作用數據發生器。換句話說,每次調用getter時都會返回一個新實例。屬性不應該像只有那些方法那樣工作。

一個可能的解決方案是實現一個自定義集合實現IList<ConnectionItem>並使用Dictionary<string, string>作爲後備存儲。然後,ConnectionStrings屬性或更好的私有字段將屬於此自定義類型,並且SerializedConnections屬性在序列化/反序列化期間的行爲將正確。