C#如何对含自定义类属性的集合使用GroupBy实现去重
问题原因
- 你当前的代码在
GroupBy分组后,将每个分组内的所有重复元素都保留了下来,遍历时会逐个输出分组内的所有元素,自然会出现重复内容。 - 若后续业务中存在
person为不同实例、仅name和family属性相同的场景,引用类型默认按内存地址比较的规则会将它们判定为不同分组,也会导致去重失效。
修复方案
方案1:最简修改(适配你当前测试代码,person为同一引用场景)
仅调整Linq查询和遍历逻辑,每个分组只取第一条数据即可:
// 每个分组仅保留第一个元素 var distinctResults = lst .GroupBy(r => r.identity) .Select(grp => grp.First()) .ToList(); // 直接遍历去重后的结果 foreach (var item in distinctResults) { Console.WriteLine(item.identity.name + " " + item.identity.family); }
方案2:通用属性分组(兼容不同person实例属性相同场景)
如果业务中会出现person实例不同但属性一致、需要判定为同一个人的情况,直接按去重依据的属性分组即可,无需修改原有类定义:
var distinctResults = lst // 按实际判定重复的属性组合分组 .GroupBy(r => new { r.identity.name, r.identity.family }) .Select(grp => grp.First()) .ToList(); foreach (var item in distinctResults) { Console.WriteLine(item.identity.name + " " + item.identity.family); }
方案3:重写相等判定逻辑(全局适用场景)
如果整个项目中都需要按name和family判定两个person是否相等,可以直接重写person类的Equals和GetHashCode方法:
public class person { public string name { get; set; } public string family { get; set; } public override bool Equals(object obj) { return obj is person p && name == p.name && family == p.family; } public override int GetHashCode() { return HashCode.Combine(name, family); } }
重写完成后,原有分组逻辑无需调整,仅需修改遍历时取每个分组第一条即可生效。
内容的提问来源于stack exchange,提问作者Amirali Sam
相关产品推荐
相关产品推荐

