C# 反序列化Json,其中一个字段有两种类型,一种类型是递归的

C# 反序列化Json,其中一个字段有两种类型,一种类型是递归的,c#,json,typescript,telerik,deserialization,C#,Json,Typescript,Telerik,Deserialization,有一个typescript部分,我从中获取json结果,需要用c#解析结果以获取用于处理它的对象,但因为我们有: 多类型字段 递归 很难理解反序列化程序的外观, 我知道我需要对多类型字段使用JsonConverter,但是如何处理沿多类型字段的递归 下面是生成json的typescript代码: 导出接口过滤器描述器{ 字段?:字符串|函数; 运算符:字符串|函数; 价值?:任何; ignoreCase?:布尔值; } 导出接口CompositeFilterDescriptor{ 逻辑:'或'|

有一个typescript部分,我从中获取json结果,需要用c#解析结果以获取用于处理它的对象,但因为我们有:

  • 多类型字段
  • 递归
  • 很难理解反序列化程序的外观, 我知道我需要对多类型字段使用JsonConverter,但是如何处理沿多类型字段的递归

    下面是生成json的typescript代码:
    导出接口过滤器描述器{
    字段?:字符串|函数;
    运算符:字符串|函数;
    价值?:任何;
    ignoreCase?:布尔值;
    }
    导出接口CompositeFilterDescriptor{
    逻辑:'或'|'和';
    过滤器:数组;
    }
    出口申报
    常量isCompositeFilterDescriptor:(源:FilterDescriptor | CompositeFilterDescriptor)=>源是CompositeFilterDescriptor问题是C#没有一个等价的“歧视联合”结构(至少,我认为这就是所谓的;-))

    多态性的唯一可用结构是接口和继承

    在这种情况下,需要两种类型(
    FilterDescriptor
    CompositeFilterDescriptor
    ),并且需要多态性,因为
    CompositeFilterDescriptor
    有一个数组可以包含这两种类型之一。在C#中,需要一个接口或基类来表示:

    interface IFilterDescriptor { }
    
    class FilterDescriptor : IFilterDescriptor
    {
        // ... (fields of FilterDescriptor)
    }
    
    class CompositeFilterDescriptor : IFilterDescriptor
    {
        public string @logic { get; set; }
        public IFilterDescriptor[] filters { get; set; }
    }
    
    此外,不能使用Json.NET默认反序列化,因为这需要多态反序列化的类型信息。但是,您可以创建一个自定义转换器,在该转换器中,您可以检查某些字段的存在,以决定如何反序列化对象:

    public class FilterDescriptorConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType) => typeof(IFilterDescriptor).IsAssignableFrom(objectType);
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject o = JObject.Load(reader);
    
            // if the 'logic' field is present, it's a CompositeFilter
            var item = o["logic"] != null 
                ? (IFilterDescriptor)new CompositeFilterDescriptor() 
                : (IFilterDescriptor)new FilterDescriptor();
            serializer.Populate(o.CreateReader(), item);
            return item;
        }
    
        public override bool CanWrite => false;
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
    }
    
    您可以这样使用它:

    var result = JsonConvert.DeserializeObject<IFilterDescriptor>(json, 
              new FilterDescriptorConverter());
    
    var result=JsonConvert.DeserializeObject(json,
    新的FilterDescriptorConverter());
    
    是值字段<代码>数字
    ?它也可以是字符串,甚至可以是类似“2,4,5”Hm的数组。。它更复杂。旁白:这是你的递归示例,最大递归次数还是更多?理论上它可以有几个层次,我的只有两个层次。