Seems like How does HashSet Compare elements for equality, but different, because that question focusses on the IEqualityComparer used by the HashSet. I want to write an Equality Comparer that declares two hashsets to be equal if SetEquals
returns true;
I have a class MyClass
, and a special IEqualityComparer<MyClass>
that compares by value: two objects of MyClass
are equal if their properties have equal values.
I have created a HashSet<MyClass>
that uses this EqualityComparer to check for equality. And I want to create a HashSetComparer (preferrably as a generic class) that returns equal if SetEquals
would return true.
some code:
var someData = ..
var myClass1 = new MyClass(someData);
var myClass2 = new MyClass(someData);
Normally these objects are not equal (reference equality)
IQualityComparer<MyClass> defaultComparer = EqualityComparer<MyClass>.Default;
Assert.IsFalse(defaultComparer.Equals(myClass1, myClass2));
But if I use my EqualityCompare, the objects appear to be equal
IQualityComparer<MyClass> valueComparer = ...
Assert.IsTrue(valueComparer.Equals(myClass1, myClass2));
So the comparer works fine. Let's create some HashSets:
// 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);
All three sets will have two elements. One that equals my1
, and one that equals my2
, using the valueComparer. A hashSet has no defined set order.
Assert.IsTrue(set1.SetEquals(set2);
Assert.IsTrue(set1.SetEquals(set3);
I want to create an equality comparer that declares two sets to be equal if they have SetQual
The equal function is easy:
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);
}
But how to write a proper GetHashCode()? There is no guarantee about the order of enumerated elements