Why implement IEqualityComparer<T> in a separate class

why not implement it on the class itself?

Because it makes no sense. The whole purpose of the IEqualityComparer<T> is to be implemented outside the type T because it targets the "reason 1" from your post.

If you want the class itself to implement the equality logic, then you are expected to implement IEquatable<T> which is provided specifically for such scenario, and EqualityComparer<T>.Default will provide the necessary bridge to your implementation anytime IEqualityComparer<T> is needed and not specified explicitly.

Since the class can provide only one hardcoded logic without any dynamic behavior and/or options, it's considered to be the default equality logic, hence the name of the static EqualityProvider<T> property providing access to it.


IComparer<T> as well as IEqualityComparer<T> work with two instances of T so they have no need to be implemented as a part of T class; however, implementing IEqualityComparer<T> within the T is a good practice, the scheme can be

  public partial class Test {
    private class TestComparer : IEqualityComparer<Test> {
      public bool Equals(Test x, Test y) { 
        return x.id == y.id && x.date == y.date; 
      }

      public int GetHashCode(Test obj) { 
        return obj.id.GetHashCode(); 
      }
    }

    // Please, note "static"
    public static IEqualityComparer<Test> MyTestComparer {get;} = new TestComparer();

    public int id { get; set; }
    public DateTime date { get; set; }
    ...
  }

In this case you just use the comparer you want:

int distinctCountComparerClass = testList.Distinct(Test.MyTestComparer).Count();

Simply put, this way you can use different ways of comparing objects from the same class depending on the context.

It's basically inversion of control: it is not for the class itself to decide how another class might want to compare its instances.

Tags:

C#

Linq

Compare