如何对对象数组调用.Distinct()?控制器中调用无效的解决办法
解决对象数组调用
Distinct()未去重的问题 你遇到的问题很典型——默认的Distinct()方法对于引用类型(比如你的ObjDTO)是通过比较对象的引用地址来判断是否相等的,而不是比较对象的属性值。也就是说,哪怕两个ObjDTO的所有属性都一模一样,只要它们是不同的实例,Distinct()就会把它们都保留下来,所以你看不到预期的去重效果。
下面给你三种常用的解决方案,你可以根据自己的场景选择:
方案1:重写ObjDTO的Equals和GetHashCode方法
这是最彻底的方式,一旦重写,之后任何地方对ObjDTO集合调用Distinct()都会按照你定义的规则来判断相等。
假设你的ObjDTO有Id(唯一标识)和Name等属性,我们可以基于Id来判断对象是否相等(你可以根据业务逻辑调整判断条件,比如结合多个属性):
public class ObjDTO { public int Id { get; set; } public string Name { get; set; } public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) return false; var other = (ObjDTO)obj; // 这里按业务逻辑判断相等,示例为只比较Id return Id == other.Id; } public override int GetHashCode() { // 要和Equals的逻辑对应,这里用Id的哈希值 return Id.GetHashCode(); } }
修改完ObjDTO后,你原来的代码就可以正常工作了:
var DistinctList = objects.Distinct();
方案2:使用Distinct的重载,传入自定义IEqualityComparer
如果你没办法修改ObjDTO类(比如它是第三方库的类),或者只是临时需要特定的去重规则,可以创建一个实现IEqualityComparer<ObjDTO>的比较器,然后传给Distinct方法。
比如我们创建一个按Id比较的比较器:
public class ObjDTOEqualityComparer : IEqualityComparer<ObjDTO> { public bool Equals(ObjDTO x, ObjDTO y) { if (x == null && y == null) return true; if (x == null || y == null) return false; return x.Id == y.Id; } public int GetHashCode(ObjDTO obj) { return obj?.Id.GetHashCode() ?? 0; } }
然后在控制器里这样调用:
var DistinctList = objects.Distinct(new ObjDTOEqualityComparer());
方案3:用GroupBy+First()临时去重
如果只是单次需求,不想写额外的类或重写方法,可以用LINQ的GroupBy按关键属性分组,然后取每组的第一个元素来模拟去重:
// 按Id分组,取每组第一个元素,实现去重 var DistinctList = objects.GroupBy(o => o.Id).Select(g => g.First());
这种方式简单快捷,但只适合临时场景,复用性不如前两种方案。
内容的提问来源于stack exchange,提问作者GeorgeB
相关产品推荐
相关产品推荐

