2016-03-26 69 views
0

我有一個OrderedDictionaryint鍵和System.Drawing.Rectangle值。 JSON.NET不會序列化OrderedDictionary ...它返回一個空對象。我寫了一個自定義轉換器,但我想知道是否有更簡單的方法。認爲JSON.NET可能使用類型化的枚舉的存在觸發使用其內置的代碼序列化和反序列化Dictionary<TKey, TValue>我嘗試這樣做:使用JSON.NET與OrderedDictionary

class Program 
{ 
    static void Main(string[] args) 
    { 
     var test = new OrderedDictionary<int, Rectangle>(); 
     test.Add(1, new Rectangle(0, 0, 50, 50)); 
     test.Add(42, new Rectangle(1, 1, 1, 1)); 

     string s = JsonConvert.SerializeObject(test); 
     var deserialized = JsonConvert.DeserializeObject<OrderedDictionary<int, Rectangle>>(s); 

     var someRect = deserialized[(object)1]; // someRect is null 
     var someOtherRect = (Rectangle)deserialized["1"]; // InvalidCastException 
    } 
} 

public class OrderedDictionary<TKey, TValue> : OrderedDictionary, IEnumerable<KeyValuePair<TKey, TValue>> 
{ 
    IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() 
    { 
     foreach (TKey key in Keys) 
     { 
      yield return new KeyValuePair<TKey, TValue>(key, (TValue)this[key]); 
     } 
    } 
} 

系列化完美的作品。但是,當我反序列化時,字典中的鍵變爲字符串,而RectangleJObject,無法轉換爲Rectangle。有什麼我可以添加到我的OrderedDictionary<>類,將允許與JSON.NET正確的反序列化?謝謝。

+0

其中OrderedDictionary ?,一個在'System.Collections.Specialized'? – Eser

+0

是的。由於我必須使用15個字符,我還會提到我閱讀[這篇文章](http://stackoverflow.com/questions/2629027/no-generic-implementation-of-ordereddictionary),並正在考慮一個很好的實現在那裏,但是擔心同樣的反序列化行爲。 –

+0

JSON.NET可能還沒有支持。您可以在https://github.com/JamesNK/Newtonsoft.Json –

回答

2

你的問題是,雖然你已經添加了一個枚舉器,但是索引器之類的東西不能被覆蓋。所以你得到的是非泛型OrderedDictionary的默認實現,它不會給你一個類型化的結果。

因此,您需要一個完全實現通用接口的外觀,而不是繼承。

你需要驗證我的班級(我只是做了測試工作)。我也欺騙了Keys和Values屬性(它們不經常使用)以及一些其他ICollection方法。只是懶惰:)

  [TestMethod] 
    public void TestJson() 
    { 
     var test = new OrderedDictionary<int, Rectangle>(); 
     test.Add(1, new Rectangle(0, 0, 50, 50)); 
     test.Add(42, new Rectangle(1, 1, 1, 1)); 
     string s = JsonConvert.SerializeObject(test); 

     var deserialized = JsonConvert.DeserializeObject<OrderedDictionary<int, Rectangle>>(s); 

     object someRect = deserialized[1]; 
     Assert.IsNotNull(someRect); 
     Assert.IsTrue(someRect is Rectangle); 
    } 

    public class OrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue> 
    { 
     private readonly OrderedDictionary dic = new OrderedDictionary(); 

     public TValue this[TKey key] { get { return default(TValue); } set { } } 

     public void Add(KeyValuePair<TKey, TValue> item) 
     { 
      dic.Add(item.Key, item.Value); 
     } 
     public void Add(TKey key, TValue value) 
     { 
      dic.Add(key, value); 
     } 

     public void Clear() { dic.Clear(); } 


     public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { } 


     public int Count { get { return dic.Count; } } 
     public bool IsReadOnly { get { return false; } } 

     public bool Contains(TKey key) { return dic.Contains(key); } 
     public bool ContainsKey(TKey key) { return dic.Contains(key); } 

     public bool Remove(TKey key) { dic.Remove(key); return true; } 

     public bool TryGetValue(TKey key, out TValue value) { value = default(TValue); return false; } 

     bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) 
     { 
      throw new NotImplementedException(); 
     } 
     bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) { return false; } 

     public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() 
     { 
      foreach (DictionaryEntry entry in dic) 
       yield return new KeyValuePair<TKey, TValue>((TKey)entry.Key, (TValue)entry.Value); 
     } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      return GetEnumerator(); 
     } 

     private static readonly TKey[] keys = new TKey[0]; 
     private static readonly TValue[] values = new TValue[0]; 

     ICollection<TKey> IDictionary<TKey, TValue>.Keys { get { return keys; } } 
     ICollection<TValue> IDictionary<TKey, TValue>.Values { get { return values; } } 
    } 
+0

不幸的是,'SortedDictionary'沒有我想要的行爲。它排序鍵...我正在尋找保持插入和刪除的順序。 –

+0

我已經更新了答案 – AndyPook