如何配置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
相关产品推荐
相关产品推荐

