I want my Food
class to be able to test whenever it is equal to another instance of Food
. I will later use it against a List, and I want to use its List.Contains()
method. Should I implement IEquatable<Food>
or just override Object.Equals()
? From MSDN:
This method determines equality by using the default equality comparer, as defined by the object's implementation of the IEquatable.Equals method for T (the type of values in the list).
So my next question is: which functions/classes of the .NET framework make use of Object.Equals()
? Should I use it in the first place?
Extending what Josh said with a practical example. +1 to Josh - I was about to write the same in my answer.
This way, I have re-usable Equals() method that works out of the box for all my derived classes.
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 ofGetHashCode
andEquals
. But for value types this required boxing.IEquatable<T>
lets a structure implement a strongly typedEquals
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 fromSystem.Object
which can make a difference if it's called frequently.As noted on Jared Parson's blog though, you still must implement the Object overrides.
According to the MSDN:
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, its 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.