我正在使用ConcreteCollectionTypeConverter来反序列化IList类型的对象。我可能做错了,因为我一直得到异常“无法将列表转换为IList”
我的对象界面看起来像这样:
[JsonObject(MemberSerialization.OptIn)]
public IMyInterface {
[JsonProperty("associatedContact")]
[JsonConverter(typeof(ConcreteCollectionTypeConverter<IList<ISomeOtherInterface>, List<SomeOtherInterface>>))]
IList<ISomeOtherInterface> MyObject { get; set; }
}
我的对象实现如下:
public MyImplementation : IMyInterface {
public List<SomeOtherImplementation> MyObject { get; set; }
public MyImplementations () {
MyObject = new List<SomeOtherImplementation>();
}
}
我的Json Converter看起来像这样:
class ConcreteCollectionTypeConverter<TInterface, TImplementation> : JsonConverter where TImplementation : TInterface
{
public override bool CanConvert(Type objectType)
{
return 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)
{
return serializer.Deserialize<TImplementation>(reader);
}
}
我在我的项目中的其他地方调用反序列化方法,如下所示:
var myDeserializedObject = JsonConvert.DeserializeObject<MyImplementation>(jsonObject.ToString());
正确解析了上面提到的我的jsonObject。
我知道这是可能的,因为我在这里看到了来自用户的评论,他已经完成了它(Casting interfaces for deserialization in JSON.NET - 对接受的答案的第一个评论。)
这种方法适用于非集合项(即使用JsonConverer(typeof(ConcreteTypeCOnverter))对接口类型IIterface MyObject的对象进行反序列化工作)。
如果我只使用列表而不是IList,我甚至不需要类型转换器,但我的要求是确保使用ICollections,因为可能存在非标准实现。
答案 0 :(得分:1)
我相信这可以满足您的需求:
public class ConcreteListTypeConverter<TInterface, TImplementation> : JsonConverter where TImplementation : TInterface
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var res = serializer.Deserialize<List<TImplementation>>(reader);
return res.ConvertAll(x => (TInterface) x);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}