这是一个非常常见的问题。使用“JsonConvert.SerializeObject”不是一个坏主意。然而,在某些情况下(通常是集合),可以使用一个技巧,即在写入时转换为接口,并在读取时反序列化为简单的派生类。
下面是一个简单的转换器,它处理可能已经被序列化为KVP集合而不像一个对象的字典(显示我的年龄:))
请注意,“WriteJson”强制转换为IDictionary<K,V>,“ReadJson”使用“DummyDictionary”。最终得到正确的结果,但使用传递的序列化程序而不会导致递归。
public class DictionaryAsKVPConverter<TKey, TValue> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
if (!objectType.IsValueType && objectType.IsGenericType)
return (objectType.GetGenericTypeDefinition() == typeof(Dictionary<,>));
return false;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dictionary = value as IDictionary<TKey, TValue>;
serializer.Serialize(writer, dictionary);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Dictionary<TKey, TValue> dictionary;
if (reader.TokenType == JsonToken.StartArray)
{
dictionary = new Dictionary<TKey, TValue>();
reader.Read();
while (reader.TokenType == JsonToken.StartObject)
{
var kvp = serializer.Deserialize<KeyValuePair<TKey, TValue>>(reader);
dictionary[kvp.Key] = kvp.Value;
reader.Read();
}
}
else if (reader.TokenType == JsonToken.StartObject)
dictionary = serializer.Deserialize<DummyDictionary>(reader);
else
dictionary = new Dictionary<TKey, TValue>();
return dictionary;
}
private class DummyDictionary : Dictionary<TKey, TValue> { }
}
CanConvert
中没有明确检查DummyDictionary
的特定原因吗? - Zev Spitzif (objectType == typeof(DummyDictionary)) {return false;}
似乎更清晰一些,然后再执行其余的检查。这将允许添加更多的灵活性:例如,任何实现IDIctionary<TKey, TValue>
的类型,或包括继承自Dictionary<TKey, TValue>
的其他类型。 - Zev Spitz