我为字典编写了一个转换器。我的想法是将其序列化为键和值列表,因此我可以为字典键编写转换器。但由于某些原因ReadJson
未调用DictionaryConverterReader
。有谁知道为什么?
public class DictionaryConverterWriter : JsonConverter
{
public override bool CanRead
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return typeof(IDictionary).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotSupportedException();
}
// Convert from Dictionary to a list of keys and values
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
serializer.Serialize(writer, null);
return;
}
else
{
var dictionary = (IDictionary)value;
serializer.Serialize(writer, new DictionaryWrapper(dictionary));
}
}
}
public class DictionaryConverterReader : JsonConverter
{
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
Debug.Log(objectType.ToString());
return objectType == typeof(DictionaryWrapper);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Debug.Log("Read");
var wrapper = serializer.Deserialize<DictionaryWrapper>(reader);
return wrapper.Unbox();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
}
[Serializable]
public class DictionaryWrapper
{
public IList keys, values;
public string type;
public string assembly;
[JsonConstructor]
private DictionaryWrapper(IList keys, IList values, string type, string assembly)
{
this.keys = keys;
this.values = values;
this.type = type;
this.assembly = assembly;
}
public DictionaryWrapper(IDictionary dictionary)
{
keys = Extra.ToList(dictionary.Keys);
values = Extra.ToList(dictionary.Values);
assembly = dictionary.GetType().Assembly.ToString();
type = dictionary.GetType().ToString();
}
public IDictionary Unbox()
{
var dictionary = (IDictionary)Activator.CreateInstance(assembly, type);
for (int i = 0; i < keys.Count; i++)
dictionary[keys[i]] = values[i];
return dictionary;
}
}
var writeSettings = new JsonSerializerSettings()
{
Converters = { new DictionaryConverterWriter() },
TypeNameHandling = TypeNameHandling.All
};
var serialized = JsonConvert.SerializeObject(new Dictionary<string, int>(), writeSettings);
var readSettings= new JsonSerializerSettings()
{
Converters = { new DictionaryConverterReader() },
TypeNameHandling = TypeNameHandling.All
};
Debug.Log(JsonConvert.DeserializeObject(serialized, readSettings)); // <-- Returns DictionaryWrapper