Reputation: 909
I have a class Pair
, which needs to have an overridden equality operator due to the two values it stores being interchangeable, the code is this
Pair.cs
public class Pair
{
protected bool Equals(Pair other)
{
return (Equals(A, other.A) && Equals(B, other.B)) || (Equals(A, other.B) && Equals(B, other.A));
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj.GetType() == this.GetType() && Equals((Pair) obj);
}
public override int GetHashCode()
{
unchecked
{
return ((A != null ? A.GetHashCode() : 0)*397) ^ (B != null ? B.GetHashCode() : 0);
}
}
public readonly Collision A, B;
public Pair(Collision a, Collision b)
{
A = a;
B = b;
}
public static bool operator ==(Pair a, Pair b)
{
if (ReferenceEquals(a, b))
return true;
if ((object)a == null || (object)b == null)
return false;
return (a.A == b.A && a.B == b.B) || (a.A == b.B && a.B == b.A);
}
public static bool operator !=(Pair a, Pair b)
{
return !(a == b);
}
}
I had ReSharper add the Equals
and GetHashCode
methods, I know Equals
is ok, but is GetHashCode
outputting the correct value?
I have a HashSet<Pair>
that I use to store the pairs, and I need to ensure there are no duplications in this list, however when I add the pairs to a HashSet
it doesn't remove the duplicates.
Just for clarification, this would be a duplicate:
Pair a = new Pair(objecta, objectb);
Pair b = new Pair(objectb, objecta);
HashSet<Pair> pairs = new HashSet<Pair>();
pairs.Add(a);
pairs.Add(b);
return pairs.Count(); //Count() returns 2 when it should be 1!
Upvotes: 2
Views: 284
Reputation: 24078
Your GetHashCode
implementation does not return the same value for (A, B) and (B, A). The HashSet
checks if it already contains a given hash at the moment of insertion. If it doesn't, then the object will be considered new.
If you correct your GetHashCode
, then at the moment of inserting the second Pair
the HashSet
will see that the hash code already exists and verify equality with the other objects sharing the same hash code.
Upvotes: 3
Reputation: 2709
Just remove this: *397
If they are considered duplicates, they must return the same int from GetHashCode(). (However, if they are not considered duplicates they are still allowed to return the same int, that will only affect performance).
Upvotes: 2