What does IEquatable<T>
buy you, exactly? The only reason I can see it being useful is when creating a generic type and forcing users to implement and write a good equals method.
What am I missing?
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.
We have written the code via Equals method so that you can see that there are two Equals methods. All the primitive supports provide the implementation for IEquatable<T> interface. Just take the above example, int implements the IEquatable<int>. Likewise, the other primitive types also implement IEquatable<T>.
Because Complex is a value type, it cannot be derived from. Therefore, the override to Equals(Object) method need not call GetType to determine the precise run-time type of each object, but can instead use the is operator in C# or the TypeOf operator in Visual Basic to check the type of the obj parameter.
From the MSDN:
The
IEquatable(T)
interface is used by generic collection objects such asDictionary(TKey, TValue)
,List(T)
, andLinkedList(T)
when testing for equality in such methods asContains
,IndexOf
,LastIndexOf
, andRemove
.
The IEquatable<T>
implementation will require one less cast for these classes and as a result will be slightly faster than the standard object.Equals
method that would be used otherwise. As an example see the different implementation of the two methods:
public bool Equals(T other) { if (other == null) return false; return (this.Id == other.Id); } public override bool Equals(Object obj) { if (obj == null) return false; T tObj = obj as T; // The extra cast if (tObj == null) return false; else return this.Id == tObj.Id; }
I'm amazed that the most important reason is not mentioned here.
IEquatable<>
was introduced mainly for structs for two reasons:
For value types (read structs) the non-generic Equals(object)
requires boxing. IEquatable<>
lets a structure implement a strongly typed Equals
method so that no boxing is required.
For structs, the default implementation of Object.Equals(Object)
(which is the overridden version in System.ValueType
) performs a value equality check by using reflection to compare the values of every field in the type. When an implementer overrides the virtual Equals method in a struct, the purpose is to provide a more efficient means of performing the value equality check and optionally to base the comparison on some subset of the struct's field or properties.
Both of which improves performance.
Reference types (read classes) don't benefit as much. The IEquatable<>
implementation does let you avoid a cast from System.Object
but that's a very trivial gain. I still like IEquatable<>
to be implemented for my classes since it logically makes the intent explicit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With