The only way to do this is to override bool Object.Equals(object other)
to return true when the conditions for equality are met, and otherwise return false. You must also override int Object.GetHashCode()
to return an int calculated from all the data that you consider when overriding Equals()
.
Note that the contract for GetHashCode()
indicates that the return value should be equal for two objects when Equals()
will return true when comparing them. This means that return 0;
is a valid implementation of GetHashCode()
, but this will cause inefficiencies when objects of your class are used as dictionary keys or stored in a HashSet<T>
.
The way to implement equality is as follows:
public class Foo : IEquatable<Foo> { public bool Equals(Foo other) { if (other == null) return false; if (other == this) return true;
An easy way to implement GetHashCode()
is to XOR together the hash codes of all the data you consider for equality in Equals()
. So, if, for example, the properties you are comparing for equality, string FirstName; string LastName; int Id;
string FirstName; string LastName; int Id;
, your implementation might look like this:
public override int GetHashCode() { return (FirstName != null ? FirstName.GetHashCode() : 0) ^ (LastName != null ? LastName.GetHashCode() : 0) ^ Id;
I usually do not redefine equality operators, since most of the time I deal with equality only for the purposes of dictionary keys or collections. I would only consider overriding equality operators if you are likely to make more comparisons by value than by reference, since it is syntactically less verbose. However, you must remember to change all places where you use ==
or !=
On your object (including when implementing Equals()
!), To use Object.ReferenceEquals()
, or to translate both operands to object
. This nasty gotcha (which can cause infinite recursion in your equality test if you're not careful) is one of the main reasons I rarely override these operators.
cdhowie
source share