Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between IEquatable and just overriding Object.Equals()?

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.

What is the difference between equals () and == in C#?

Difference between == and . Equals method in c# The Equality Operator ( ==) is the comparison operator and the Equals() method in C# is used to compare the content of a string. The Equals() method compares only content.

How do you override equals method in object class?

Can we override the equals() method in Java? To compare two objects the object class provides a method with name equals(), this method accepts an object and compares it with the current object. If the references of these two objects are equal, then it returns true else this method returns false.

Should override equals C#?

With value types, you should always override the == operator. Like the Equals method, the default implementation of the == operator uses reflection and is slow. Use the same logic as the Equals method, and you'll get much better performance when you're doing equality comparisons on value types.


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 of Object.Equals(Object) and GetHashCode so that their behavior is consistent with that of the IEquatable<T>.Equals method. If you do override Object.Equals(Object), your overridden implementation is also called in calls to the static Equals(System.Object, System.Object) method on your class. This ensures that all invocations of the Equals 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.


Extending what Josh said with a practical example. +1 to Josh - I was about to write the same in my answer.

public abstract class EntityBase : IEquatable<EntityBase>
{
    public EntityBase() { }

    #region IEquatable<EntityBase> Members

    public bool Equals(EntityBase other)
    {
        //Generic implementation of equality using reflection on derived class instance.
        return true;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as EntityBase);
    }

    #endregion
}

public class Author : EntityBase
{
    public Author() { }
}

public class Book : EntityBase
{
    public Book() { }
}

This way, I have re-usable Equals() method that works out of the box for all my derived classes.