鉴于这些类定义:
public class TypeConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => serializer.Serialize(writer, value);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => serializer.Deserialize<T>(reader);
}
public interface ISubStuff
{
string Item { get; set; }
}
public class SubStuff : ISubStuff
{
public string Item { get; set; }
}
public interface IMainStuff
{
Dictionary<string, ISubStuff> SubStuff { get; set; }
}
我正在尝试在方法声明中使用TypeConverter类进行反序列化,如下所示,但它不起作用:
public class MainStuff : IMainStuff
{
[JsonConverter(typeof(TypeConverter<Dictionary<string, SubStuff>>))]
public Dictionary<string, ISubStuff> SubStuff
{
get;
set;
}
}
以下调用反序列化json会导致unable to cast object of type Dictionary<string, SubStuff> to Dictionary<string, ISubStuff>
异常。
var jsonText = "{ \"SubStuff\": { } }";
var deser = JsonConvert.DeserializeObject<MainStuff><jsonText);
答案 0 :(得分:2)
您的问题是c#Dictionary<TKey, TValue>
不是covariant。即,即使SubStuff
是 ISubStuff
,Dictionary<string, SubStuff>
is not a Dictionary<string, ISubStuff>
。因此,当Json.NET尝试将Dictionary<string, SubStuff>
设置回MainStuff.SubStuff
属性时,会抛出InvalidCastException
。
有关读/写集合不协变的一般解释,请参阅this answer。它对List<T>
缺乏协方差的讨论同样适用于通用词典。
您可以使用JsonProperty.ItemConverterType
仅将TypeConverter<T>
应用于词典中的值,如下所示:
public class MainStuff : IMainStuff
{
[JsonProperty(ItemConverterType = typeof(TypeConverter<SubStuff>))]
public Dictionary<string, ISubStuff> SubStuff
{
get;
set;
}
}
public class TypeConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
var msg = string.Format("This converter should be applied directly with [JsonProperty(ItemConverterType = typeof(TypeConverter<{0}>))] or [JsonProperty(typeof(TypeConverter<{0}>))]",
typeof(T));
throw new NotImplementedException(msg);
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return serializer.Deserialize<T>(reader);
}
}
示例fiddle。
顺便说一下,您可以继承CustomCreationConverter<>
而不是继承JsonConverter
:
public class MainStuff : IMainStuff
{
[JsonProperty(ItemConverterType = typeof(TypeConverter<ISubStuff, SubStuff>))]
public Dictionary<string, ISubStuff> SubStuff
{
get;
set;
}
}
public class TypeConverter<T, TSerialized> : CustomCreationConverter<T>
where TSerialized : T, new()
{
public override T Create(Type objectType)
{
return new TSerialized();
}
}
示例fiddle #2。
最后,作为替代方案,您可以调查TypeNameHandling
setting。