You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:43:31