.NET 8中Statistics<T>类的System.Text.Json序列化反序列化问题
解决方案:让Statistics实现IDictionary<int, T>接口
要让Statistics<T>的序列化/反序列化格式与Dictionary<int, T>完全一致,且无需修改外部调用方的JsonSerializerOptions,只需修改Statistics<T>类本身,让它实现IDictionary<int, T>接口——System.Text.Json会默认将实现该接口的类型以字典格式(JSON键值对对象)处理,和原生Dictionary的输出完全匹配。
修改后的完整类代码:
using System.Collections; using System.Collections.Generic; using System.Text.Json.Serialization; namespace SerializeCustomEnumerable; public class Statistics<T> : IEnumerable<(int Year, T Value)>, IDictionary<int, T> where T : new() { // 添加[JsonInclude]让序列化器能访问protected成员,用于反序列化重建 [JsonInclude] protected Dictionary<int, T> Years { get; set; } = new Dictionary<int, T>(); public Statistics() { } public Statistics(Dictionary<int, T> years) { Years = years ?? throw new ArgumentNullException(nameof(years)); } public T this[int year] { get { return Years.TryGetValue(year, out var value) ? value : new T(); } set { Years[year] = value; } } // 直接委托底层Years字典实现IDictionary接口成员 public ICollection<int> Keys => Years.Keys; public ICollection<T> Values => Years.Values; public int Count => Years.Count; public bool IsReadOnly => false; public void Add(int key, T value) => Years.Add(key, value); public bool ContainsKey(int key) => Years.ContainsKey(key); public bool Remove(int key) => Years.Remove(key); public bool TryGetValue(int key, out T value) => Years.TryGetValue(key, out value); public void Add(KeyValuePair<int, T> item) => Years.Add(item.Key, item.Value); public void Clear() => Years.Clear(); public bool Contains(KeyValuePair<int, T> item) => Years.Contains(item); public void CopyTo(KeyValuePair<int, T>[] array, int arrayIndex) => ((ICollection<KeyValuePair<int, T>>)Years).CopyTo(array, arrayIndex); public bool Remove(KeyValuePair<int, T> item) => ((ICollection<KeyValuePair<int, T>>)Years).Remove(item); // 保留原有枚举逻辑 public IEnumerator<(int Year, T Value)> GetEnumerator() { foreach (var element in Years) { yield return (element.Key, element.Value); } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator<KeyValuePair<int, T>> IEnumerable<KeyValuePair<int, T>>.GetEnumerator() => Years.GetEnumerator(); }
关键说明:
- 实现
IDictionary<int, T>后,System.Text.Json自动以字典格式序列化/反序列化,输出与Dictionary<int, T>完全一致的JSON。 [JsonInclude]确保protected的Years字段能被序列化器访问,反序列化时正确重建对象。- 所有ID接口方法直接委托给底层字典,无需额外逻辑,保留原有类的全部功能。
内容的提问来源于stack exchange,提问作者suchoss
相关产品推荐
相关产品推荐

