2016-03-26 8 views
0

OrderedDictionary私はintのキーとSystem.Drawing.Rectangleの値を持っています。 JSON.NETはOrderedDictionaryをシリアル化しません...空のオブジェクトを返します。私はカスタムコンバーターを書いたが、もっと簡単な方法があるのか​​疑問に思った。 JSON.NETはDictionary<TKey, TValue>のシリアライズとデシリアライズのための内蔵のコードを使用するトリガとして型付けされた列挙子の存在を使用するかもしれないことを考えると、私はこれを試してみました:OrderedDictionaryでJSON.NETを使用

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]); 
     } 
    } 
} 

シリアライゼーション完璧に動作します。ただし、逆シリアル化すると、辞書のキーは文字列になり、Rectangleはに変換できないJObjectです。 OrderedDictionary<>クラスにJSON.NETで適切なデシリアライズを追加できるものがありますか?ありがとう。

+0

「System.Collections.Specialized」のどれですか? – Eser

+0

はい。私は15文字を使用しなければならないので、私は[この記事](http://stackoverflow.com/questions/2629027/no-generic-implementation-of-ordereddictionary)を読んで、良い実装の1つを考えていますそこでは、同じ非直列化の動作を恐れています。 –

+0

JSON.NETはこれをまだサポートしていない可能性があります。この質問を投稿するにはhttps://github.com/JamesNK/Newtonsoft.Json –

答えて

2

問題は、列挙子を追加したにもかかわらず、インデクサーのようなものは上書きできないということです。だからあなたが得ているのは、あなたに型付きの結果を与えない非ジェネリックOrderedDictionaryのデフォルトの実装です。

したがって、継承する代わりに、汎用インターフェースを完全に実装するファサードが必要です。

私のクラスを検証する必要があります(テストしたばかりです)。私はまた、キーと値のプロパティ(頻繁に使用されることはありません)と他の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

関連する問題