I want to know the best way to compare two objects and to find out if they’re equal. I’m overriding both GethashCode and Equals. So a basic class looks like:
public class Test
{
public int Value { get; set; }
public string String1 { get; set; }
public string String2 { get; set; }
public override int GetHashCode()
{
return Value ^ String1.GetHashCode() ^ String2.GetHashCode();
}
public override bool Equals( object obj )
{
return GetHashCode() == obj.GetHashCode();
}
}
So for testing purposes I created two objects:
Test t = new Test()
{
Value = 1,
String1 ="One",
String2 = "One"
};
Test t2 = new Test()
{
Value = 1,
String1 = "Two",
String2 = "Two"
};
bool areEqual = t.Equals( t2 );
In testing this areEqual returns true event though both objects are different. I realise this is because String1 and String2 are the same value in each object and thus cancels each other out when hashing.
Is there a better way off hashing object that the method I have that will resolve my issue?
Your current equality method is broken – there are more values than possible hash codes. It’s entirely reasonable (and expected) that you will occasionally have values which are unequal but give the same hash. Equals should check the actual values:
A few things to note:
Your way of generating the hashcode will give the same value for any fixed
ValueifString1andString2are the same; it will also blow up ifString1orString2is null. This is an unfortunate aspect of using XOR for hashing. I prefer something like this:Generally speaking, equality becomes tricky when inheritance gets involved. You may want to consider sealing your class.
You may also want to implement
IEquatable<Test>