我有一个通用类型 Container<IContentType>
接口(interface)在哪里IContentType
可以是四个具体之一ContentX
类型。
我序列化了,一切都很好。
使用 Newtonsoft 反序列化时,我使用自定义类型转换器和 var model = JsonConvert.DeserializeObject<Container<ContentA>>(json, settings)
作品。调试器显示我有一个 Container<ContentA>
对象。
我的计划是在反序列化时尝试对四种可能的 ContentX
中的每一个进行反序列化。类型并默默地捕获异常,直到我“猜出”正确的异常。
但是,如果我在这样的方法中执行此操作:
public static Container<IContentType> Deserialize(jsonfile)
{
...
var model = JsonConvert.DeserializeObject<Container<ContentA>>(json, settings)
return model;
}
我收到“无法将 Container<ContentA>
隐式转换为 Container<IContentType>
”。 ContentA
实现IContentType
.
有没有办法可以创建强制转换运算符、转换、动态或使隐式转换起作用?
最佳答案
而不是尝试反序列化为 Container<ContentX>
适用于混凝土类型 X
,您应该反序列化为 Container<IContentType>
使用custom JsonConverter
将 JSON 预加载到 JToken
中并按照 How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects? 推断具体类型或Deserializing polymorphic json classes without type information using json.net或Json.Net Serialization of Type with Polymorphic Child Object .
因此您的转换器将类似于:
public class ContentConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(IContentType);
}
Type GetConcreteType(JObject obj)
{
if (obj.GetValue(nameof(ContentA.SomePropertyOfContentA), StringComparison.OrdinalIgnoreCase) != null)
return typeof(ContentA);
// Add other tests for other content types.
// Return a default type or throw an exception if a unique type cannot be found.
throw new JsonSerializationException("Cannot determine concrete type for IContentType");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var obj = JObject.Load(reader);
var concreteType = GetConcreteType(obj);
return obj.ToObject(concreteType, serializer);
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
您可以调用 JsonConvert
看起来像:
var settings = new JsonSerializerSettings
{
Converters = { new ContentConverter() },
};
var model = JsonConvert.DeserializeObject<Container<IContentType>>(json, settings);
最后,您可以使用完全自动选择类型
new JsonDerivedTypeConverer<IContentType>(typeof(ContentA), typeof(ContentB), typeof(ContentC), typeof(ContentD))
哪里JsonDerivedTypeConverer<T>
取自JsonConverter with Interface .
关于c# - 反序列化泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46715112/