Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When To Use IEquatable<T> And Why

Tags:

c#

iequatable

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?

like image 317
Jack Kada Avatar asked Mar 19 '10 11:03

Jack Kada


People also ask

What is the point of IEquatable?

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.

Does INT implement IEquatable?

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>.

How do you override equals method in C#?

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.


2 Answers

From the MSDN:

The IEquatable(T) interface is used by generic collection objects such as Dictionary(TKey, TValue), List(T), and LinkedList(T) when testing for equality in such methods as Contains, IndexOf, LastIndexOf, and Remove.

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; } 
like image 155
Cornelius Avatar answered Sep 20 '22 23:09

Cornelius


I'm amazed that the most important reason is not mentioned here.

IEquatable<> was introduced mainly for structs for two reasons:

  1. 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.

  2. 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.

like image 26
nawfal Avatar answered Sep 20 '22 23:09

nawfal