C# Newtonsoft.Json:不使用Json特性反序列化嵌套接口
无特性实现接口反序列化(解决IC实例创建失败问题)
问题根源
你的代码反序列化时抛出Could not create an instance of type DeserializeInterfaces.IC异常,核心原因是:CustomInterfaceConverter.ReadJson方法里调用jsonObject.ToObject<B>()时,没有传入当前的JsonSerializer实例。这导致Json.NET反序列化B对象的c属性(IC类型)时,无法触发自定义转换器,默认逻辑无法实例化接口类型。
解决方案
修改自定义转换器的ReadJson方法,调用ToObject时传入当前serializer,同时优化类型判断逻辑(避免依赖类型名称,提升健壮性),并补充实现WriteJson方法(避免序列化时报错)。
修改后的完整代码
using System; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace DeserializeInterfaces { public class CustomInterfaceConverter : JsonConverter { public override bool CanConvert(Type objectType) { // 直接匹配目标接口类型,比判断名称更可靠 return objectType == typeof(IB) || objectType == typeof(IC); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JObject jsonObject = JObject.Load(reader); if (objectType == typeof(IB)) { // 传入serializer,让嵌套的IC属性反序列化也使用当前转换器 return jsonObject.ToObject<B>(serializer); } if (objectType == typeof(IC)) { return jsonObject.ToObject<C>(serializer); } throw new NotSupportedException($"无法反序列化类型 {objectType}"); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // 直接序列化对象的实际类型,避免序列化报错 serializer.Serialize(writer, value); } } public interface IA { IB b { get; set; } } public class A : IA { public IB b { get; set; } } public interface IB { IC c { get; set; } } public class B : IB { public IC c { get; set; } } public interface IC { int v { get; set; } } public class C : IC { public int v { get; set; } } class Program { static void Main(string[] args) { CustomInterfaceConverter jsonConverter = new CustomInterfaceConverter(); IA a = new A(); a.b = new B(); a.b.c = new C(); a.b.c.v = 1; string aSer = JsonConvert.SerializeObject(a, jsonConverter); A aDeser = JsonConvert.DeserializeObject<A>(aSer, jsonConverter); // 验证反序列化结果 Console.WriteLine(aDeser.b.c.v); // 输出1 } } }
关键修改点说明
- CanConvert逻辑优化:直接判断
objectType是否等于目标接口类型,避免依赖类型名称带来的潜在问题(比如类型重名、命名空间变更)。 - ReadJson传入serializer:调用
jsonObject.ToObject<T>(serializer)时传入当前序列化器,确保嵌套接口类型(如B中的IC)反序列化时也能触发自定义转换器。 - 补充WriteJson实现:实现序列化逻辑,直接序列化对象的实际类型,避免调用
JsonConvert.SerializeObject时抛出NotImplementedException。
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

