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

如何配置JSON反序列化时将IList<T>属性实例化为ObservableCollection<T>

如何在System.Text.Json反序列化时将所有IList属性实例化为ObservableCollection

问题背景

我有一批用于映射JSON结构的C#类,其中JSON数组对应的属性都被声明为IList<T>类型(T为多种不同类型),而且无法修改这些类的代码。现在需要实现:将JSON反序列化为根类型MyClass时,所有IList<T>类型的属性(包括深层嵌套的属性)都自动实例化为ObservableCollection<T>。

示例类结构

class MyClass{
    public IList<NestedClass> MyList { get; set; }
}

class NestedClass{
    public IList<AnotherNestedClass> NestedList { get; set; }
}

class AnotherNestedClass{
    // 其他属性
}

期望效果

var obj = JsonSerializer.Deserialize<MyClass>(jsonString);
Console.WriteLine(obj?.MyList?.GetType()); // 输出:System.Collections.ObjectModel.ObservableCollection`1[NestedClass]

解决方案

通过实现自定义JsonConverterFactory,可以全局处理所有IList<T>类型的反序列化逻辑,自动将其实例化为ObservableCollection<T>。

1. 实现自定义转换器工厂

using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;

public class ObservableCollectionConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert)
    {
        // 匹配所有IList<T>泛型接口类型
        return typeToConvert.IsInterface 
            && typeToConvert.IsGenericType 
            && typeToConvert.GetGenericTypeDefinition() == typeof(IList<>);
    }

    public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options)
    {
        // 获取IList<T>中的元素类型T
        var elementType = type.GetGenericArguments()[0];
        // 创建对应泛型的转换器实例
        var converterType = typeof(ObservableCollectionConverter<>).MakeGenericType(elementType);
        return (JsonConverter)Activator.CreateInstance(converterType);
    }

    // 泛型转换器,处理具体的反序列化逻辑
    private class ObservableCollectionConverter<T> : JsonConverter<IList<T>>
    {
        public override IList<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // 先利用内置逻辑反序列化为List<T>,再转换为ObservableCollection<T>
            var list = JsonSerializer.Deserialize<List<T>>(ref reader, options);
            return list != null ? new ObservableCollection<T>(list) : new ObservableCollection<T>();
        }

        public override void Write(Utf8JsonWriter writer, IList<T> value, JsonSerializerOptions options)
        {
            // 序列化时按IEnumerable<T>处理,兼容所有集合类型
            JsonSerializer.Serialize(writer, (IEnumerable<T>)value, options);
        }
    }
}

2. 反序列化时使用该转换器

var options = new JsonSerializerOptions();
options.Converters.Add(new ObservableCollectionConverterFactory());

var obj = JsonSerializer.Deserialize<MyClass>(jsonString, options);
// 验证结果
Console.WriteLine(obj?.MyList?.GetType()); // 输出ObservableCollection<NestedClass>
Console.WriteLine(obj?.MyList?[0]?.NestedList?.GetType()); // 深层嵌套属性同样是ObservableCollection<AnotherNestedClass>

原理说明

  • 转换器工厂ObservableCollectionConverterFactory会自动识别所有IList<T>接口类型,为每个不同的元素类型T创建对应的泛型转换器。
  • 反序列化时,先借助内置的JSON序列化逻辑将数组转为List<T>,再包装成ObservableCollection<T>实例。
  • 该方案支持所有层级的嵌套IList<T>属性,无需逐个手动处理。

内容的提问来源于stack exchange,提问作者Marc Miller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:48:41