What's the difference between IEquatable and just overriding Object.Equals()?
The main reason is performance. When generics were introduced in .NET 2.0 they were able to add a bunch of neat classes such as List<T>
, Dictionary<K,V>
, HashSet<T>
, etc. These structures make heavy use of GetHashCode
and Equals
. But for value types this required boxing. IEquatable<T>
lets a structure implement a strongly typed Equals
method so no boxing is required. Thus much better performance when using value types with generic collections.
Reference types don't benefit as much but the IEquatable<T>
implementation does let you avoid a cast from System.Object
which can make a difference if it's called frequently.
As noted on Jared Parson's blog though, you must still implement the standard Object.Equals
and Object.GetHashcode
overrides.
According to the MSDN:
If you implement
IEquatable<T>
, you should also override the base class implementations ofObject.Equals(Object)
andGetHashCode
so that their behavior is consistent with that of theIEquatable<T>.Equals
method. If you do overrideObject.Equals(Object)
, your overridden implementation is also called in calls to the staticEquals(System.Object, System.Object)
method on your class. This ensures that all invocations of theEquals
method return consistent results.
So it seems that there's no real functional difference between the two except that either could be called depending on how the class is used. From a performance standpoint, it's better to use the generic version because there's no boxing/unboxing penalty associated with it.
From a logical standpoint, it's also better to implement the interface. Overriding the object doesn't really tell anyone that your class is actually equatable. The override may just be a do nothing class or a shallow implementation. Using the interface explicitly says, "Hey, this thing is valid for equality checking!" It's just better design.