我有一个OrderedDictionary,它有int键和System.Drawing.Rectangle值。JSON.NET不会序列化OrderedDictionary...it返回空对象。我写了一个自定义转换器,但我想知道是否有更简单的方法。考虑到JSON.NET可能使用类型化枚举数的存在作为触发器,使用其内置代码来序列化和反序列化Dictionary<TKey, TValue>,我尝试了以下操作:
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]);
}
}
}序列化工作得很好。但是,当我反序列化时,字典中的键变成字符串,而Rectangles是不能转换到Rectangle的JObjects。我是否可以在我的OrderedDictionary<>类中添加一些东西,允许使用JSON.NET进行适当的反序列化?谢谢。
发布于 2016-03-27 10:10:42
您的问题是,虽然您已经添加了一个枚举数,但是像索引器这样的东西不能被覆盖。因此,您得到的是非泛型OrderedDictionary的默认实现,它不会给您输入结果。
因此,您不需要继承,而是需要一个完全实现泛型接口的外观。
您需要验证我的类(我刚刚完成了测试)。我还欺骗了密钥和值属性(它们并不经常使用)和其他一些ICollection方法。只是懒惰:)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using Newtonsoft.Json;
using Xunit;
namespace XUnitTestProject1
{
public class UnitTest1
{
[Fact]
public void TestJsonRectange()
{
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 json = JsonConvert.SerializeObject(test);
var deserialized = JsonConvert.DeserializeObject<OrderedDictionary<int, Rectangle>>(json);
object someRect = deserialized[1];
Assert.NotNull(someRect);
Assert.True(someRect is Rectangle);
}
[Fact]
public void TestJsonString()
{
var test = new OrderedDictionary<string, string>();
test.Add("1", "11");
test.Add("42", "4242");
string json = JsonConvert.SerializeObject(test);
var deserialized = JsonConvert.DeserializeObject<OrderedDictionary<string, string>>(json);
object something = deserialized["1"];
Assert.NotNull(something);
Assert.True(something is string);
}
public class OrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
private readonly OrderedDictionary dic = new OrderedDictionary();
public TValue this[TKey key] { get { return (TValue)dic[key]; } set { dic[key] = value; } }
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; } }
}
}
}https://stackoverflow.com/questions/36239245
复制相似问题