如何让Json.Net反序列化时自动忽略列表中的重复项
前置说明
你给出的JSON示例存在语法错误,numbers字段应该是数组格式(用[]包裹)而非对象格式,修正后的正确JSON结构如下:
{ "numbers": [ 1, 2, 3, 3 ] }
方案1:属性setter直接去重(最简单实现)
无需修改Json.Net配置,直接修改实体类属性的赋值逻辑即可:
public class Test { private List<int> _numbers; [JsonProperty("numbers")] public List<int> Numbers { get => _numbers; set => _numbers = value.Distinct().ToList(); } }
方案2:自定义JsonConverter(可复用,适合多场景/全局配置)
如果需要在多个列表属性上复用去重逻辑,可以自定义专属转换器:
第一步:实现int列表去重转换器
public class DistinctIntListConverter : JsonConverter<List<int>> { public override List<int> ReadJson(JsonReader reader, Type objectType, List<int> existingValue, bool hasExistingValue, JsonSerializer serializer) { var list = serializer.Deserialize<List<int>>(reader); return list?.Distinct().ToList() ?? new List<int>(); } public override void WriteJson(JsonWriter writer, List<int> value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
第二步:使用转换器
两种使用方式按需选择:
- 仅作用于指定属性:
public class Test { [JsonProperty("numbers")] [JsonConverter(typeof(DistinctIntListConverter))] public List<int> Numbers { get; set;} }
- 全局注册,所有
List<int>反序列化时自动去重:
var serializeSettings = new JsonSerializerSettings { Converters = new List<JsonConverter> { new DistinctIntListConverter() } }; // 反序列化时传入配置 var result = JsonConvert.DeserializeObject<Test>(jsonContent, serializeSettings);
方案3:泛型通用去重转换器(支持所有类型列表)
如果需要适配不同类型的列表(比如List<long>、List<string>等),可以实现泛型版本的转换器:
public class DistinctListConverter<T> : JsonConverter<List<T>> { public override List<T> ReadJson(JsonReader reader, Type objectType, List<T> existingValue, bool hasExistingValue, JsonSerializer serializer) { var list = serializer.Deserialize<List<T>>(reader); return list?.Distinct().ToList() ?? new List<T>(); } public override void WriteJson(JsonWriter writer, List<T> value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
使用时指定对应类型即可:
[JsonConverter(typeof(DistinctListConverter<int>))] public List<int> Numbers { get; set;}
提示:如果需要对引用类型的列表去重,需要给
Distinct方法传入自定义的IEqualityComparer<T>实现,否则默认按引用地址比较。
内容的提问来源于stack exchange,提问作者Lemon
相关产品推荐
相关产品推荐

