首页 > 解决方案 > 哈希集EqualityComparer 返回相等 if SetEquals: which GetHashCode?

问题描述

似乎HashSet 如何比较元素是否相等,但有所不同,因为该问题集中在 HashSet 使用的 IEqualityComparer 上。我想编写一个相等比较器,如果SetEquals返回 true,则声明两个哈希集相等;

我有一个 classMyClass和一个IEqualityComparer<MyClass>按值比较的特殊对象:MyClass如果它们的属性具有相等的值,则它们的两个对象相等。

我创建了一个HashSet<MyClass>使用此 EqualityComparer 来检查相等性的方法。我想创建一个 HashSetComparer(最好作为一个泛型类),如果SetEquals返回 true,则返回相等。

一些代码:

var someData = ..
var myClass1 = new MyClass(someData);
var myClass2 = new MyClass(someData);

通常这些对象不相等(引用相等)

IQualityComparer<MyClass> defaultComparer = EqualityComparer<MyClass>.Default;
Assert.IsFalse(defaultComparer.Equals(myClass1, myClass2));

但是如果我使用我的 EqualityCompare,对象似乎是相等的

IQualityComparer<MyClass> valueComparer = ...
Assert.IsTrue(valueComparer.Equals(myClass1, myClass2));

所以比较器工作正常。让我们创建一些 HashSet:

// two unequal MyClass object
MyClass my1 = ...
MyClass my2 = ...
Assert.IsFalse(valueComparer.Equals(my1, my2);

var sequence1 = new MyClass[] {my1, my2};
var sequence2 = new MyClass[] {my2, my1};
var sequence3 = new MyClass[] {my1, my1, my2, my1, my2, my2}

var set1 = new HashSet<MyClass>(sequence1, valueComparer);
var set2 = new HashSet<MyClass>(sequence2, valueComparer);
var set3 = new HashSet<MyClass>(sequence3, valueComparer);

所有三组将有两个元素。一个等于my1,一个等于my2,使用 valueComparer。hashSet 没有定义的集合顺序。

Assert.IsTrue(set1.SetEquals(set2);
Assert.IsTrue(set1.SetEquals(set3);

我想创建一个相等比较器,如果它们有,则声明两组相等SetQual

equal函数很简单:

public bool Equals(HashSet<MyClass> x, HashSet<MyClass> y)
{
    if (x == null) return y == null;               // both x and y null
    if (y == null) return false;                   // y null, but x not null
    if (object.ReferenceEquals(x, y)) return true; // x and y same object
    if (x.GetType() != y.GetType()) return false;  // x and y different type

    return x.SetEquals(y);
}

但是如何编写一个正确的 GetHashCode() 呢?无法保证枚举元素的顺序

标签: c#hashsetgethashcode

解决方案


推荐阅读