1

I've been researching IEqualityComparer and IEquitable.

From posts such as What is the difference between IEqualityComparer<T> and IEquatable<T>? the difference between the two is now clear. "IEqualityComparer is an interface for an object that performs the comparison on two objects of the type T."

Following the example at https://msdn.microsoft.com/en-us/library/ms132151(v=vs.110).aspx the purpose of IEqualityComparer is clear and simple.

I've followed the example at https://dotnetcodr.com/2015/05/05/implementing-the-iequatable-of-t-interface-for-object-equality-with-c-net/ to work out how to use it and I get the following code:

class clsIEquitable
{
    public static void mainLaunch()
    {
        Person personOne = new Person() { Age = 6, Name = "Eva", Id = 1 };
        Person personTwo = new Person() { Age = 7, Name = "Eva", Id = 1 };

        //If Person didn't inherit from IEquatable, equals would point to different points in memory.
        //This means this would be false as both objects are stored in different locations

        //By using IEquatable on class it compares the objects directly
        bool p = personOne.Equals(personTwo);

        bool o = personOne.Id == personTwo.Id;

        //Here is trying to compare and Object type with Person type and would return false.
        //To ensure this works we added an overrides on the object equals method and it now works
        object personThree = new Person() { Age = 7, Name = "Eva", Id = 1 };
        bool p2 = personOne.Equals(personThree);

        Console.WriteLine("Equatable Check", p.ToString());

    }
}


public class Person : IEquatable<Person>
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public bool Equals(Person other)
    {
        if (other == null) return false;
        return Id == other.Id;
    }


    //These are to support creating an object and comparing it to person rather than comparing person to person

    public override bool Equals(object obj)
    {
        if (obj is Person)
        {
            Person p = (Person)obj;
            return Equals(p);
        }
        return false;
    }

    public override int GetHashCode()
    {
        return Id;
    }

}

My question is WHY would I use it? It seems like a lot of extra code to the simple version below (bool o):

        //By using IEquatable on class it compares the objects directly
    bool p = personOne.Equals(personTwo);

    bool o = personOne.Id == personTwo.Id;
Community
  • 1
  • 1
Jay
  • 878
  • 3
  • 12
  • 22
  • 4
    *You* know you want to compare persons by `Id`. How is any random collection that stores a `Person` supposed to know? – Jeroen Mostert Jun 09 '16 at 16:25
  • 1
    And supposing you want to add an extra metric for comparing `Person`s. What then? Will you go around looking for all instances where two `Person`s are compared and refactor those, or just edit the `Equals` implementation? This is one typical example of code reusing. – EvilTak Jun 09 '16 at 16:30
  • Its so simple once its pointed out! Thanks – Jay Jun 10 '16 at 08:00

1 Answers1

5

IEquatable<T> is used by generic collections to determine equality.

From this msdn article https://msdn.microsoft.com/en-us/library/ms131187.aspx

The IEquatable interface is used by generic collection objects such as Dictionary, List, and LinkedList when testing for equality in such methods as Contains, IndexOf, LastIndexOf, and Remove. It should be implemented for any object that might be stored in a generic collection.

This provides an added benefit when using structs, since calling the IEquatable<T> equals method does not box the struct like calling the base object equals method would.

yeah-buddy
  • 424
  • 3
  • 6