C#使用自定义比较器获取字典自定义对象去重结果异常问题咨询
问题解答
1. 比较器未触发执行的原因
- LINQ的
Distinct属于延迟执行的查询算子,你写的var uniques = map.Distinct(new MyComparer());只是构造了查询表达式,没有实际执行计算,所以不会进入比较器的逻辑。 - 你需要对结果进行枚举操作才会触发执行,比如调用
.ToList()、.ToArray(),或者用foreach遍历uniques变量,这时候断点就会命中了。
2. 当前MyComparer无法实现去重的问题
你当前的比较器存在两个核心逻辑错误,无法完成Vector按属性值去重的需求:
错误1:Vector的比较逻辑错误
Vector是引用类型,默认的==运算符比较的是对象的内存引用地址,而不是对象的属性值。你循环中每次new Vector()创建的都是不同的实例,就算四个属性完全一致,x.Key == y.Key也会返回false,自然无法去重。
错误2:GetHashCode实现不合理
你当前返回固定值1虽然能强制触发Equals比较,但会极大降低查询效率,数据量稍大就会有明显性能问题。
正确实现方案
你可以直接针对字典的Key(Vector集合)做去重,调整实现如下:
方案1:修改比较器直接适配Vector类型(更简洁,符合你获取去重Vector的需求)
class VectorComparer : IEqualityComparer<Vector> { public bool Equals(Vector x, Vector y) { // 空值判断可根据自己的业务场景补充 return x.A == y.A && x.B == y.B && x.C == y.C && x.D == y.D; } public int GetHashCode(Vector obj) { // 组合属性生成哈希码,低版本C#可替换为自定义哈希计算逻辑 return HashCode.Combine(obj.A, obj.B, obj.C, obj.D); } }
调用代码:
// 直接对Vector去重,ToList触发查询执行 var uniqueVectors = map.Keys.Distinct(new VectorComparer()).ToList();
方案2:如果需要保留KeyValuePair结构,修改原MyComparer即可
class MyComparer : IEqualityComparer<KeyValuePair<Vector, int>> { public bool Equals(KeyValuePair<Vector, int> x, KeyValuePair<Vector, int> y) { return x.Key.A == y.Key.A && x.Key.B == y.Key.B && x.Key.C == y.Key.C && x.Key.D == y.Key.D; } public int GetHashCode(KeyValuePair<Vector, int> obj) { return HashCode.Combine(obj.Key.A, obj.Key.B, obj.Key.C, obj.Key.D); } }
调用代码:
var uniques = map.Distinct(new MyComparer()).ToList();
内容的提问来源于stack exchange,提问作者Arie
相关产品推荐
相关产品推荐

