Why embed IEqualityComparer <T> in a separate class

When I looked at the common interface IEqualityCompareron msdn , I noticed that the interface was implemented in a separate class called "Comparer" IEquatable<T>, which is implemented in the class itself. When I looked for a few more examples, each of them used a separate class, and I wondered: why not implement it in the class itself?

I can imagine that the override object.Equalsand object.GetHashCodeis not considered good practice because it is used in many different situations, but even msdn says (my account):

This interface allows you to implement individual equality comparisons for collections .

therefore its use is largely limited to Linq. There are only 2 reasons why I can understand why defining a separate comparison class:

  • The various methods in the class collection require a different comparison.
  • The class is large and an instance of another object is undesirable (although if this is really a problem, why doesn’t it have a whole collection, is this good?).

So my question is:

Is there any special reason that I overlook that forces everyone to define a different comparative class just for comparison, instead of just implementing an interface for the class itself (which is no worse, in my opinion, at least)?

A small example:

public static void Main(string[] args)
{
    Test t1 = new Test { id = 1, date = default(DateTime) };
    Test t2 = new Test { id = 1, date = default(DateTime) };
    Test t3 = new Test { id = 0, date = default(DateTime) };
    List<Test> testList = new List<Test>{ t1, t2, t3 };

    //Same result
    int distinctCountClass = testList.Distinct(new Test()).Count();
    int distinctCountComparerClass = testList.Distinct(new TestComparer()).Count();
}

public partial class Test
{
    public int id { get; set; }
    public DateTime date { get; set; }
}

public partial class Test : 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(); }
}

public 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(); }
}
+4
source share
3 answers

?

. IEqualityComparer<T> T, " 1" .

, , IEquatable<T>, , EqualityComparer<T>.Default IEqualityComparer<T> .

- / , , EqualityProvider<T>, .

+3

IComparer<T>, IEqualityComparer<T> T, T; IEqualityComparer<T> T ,

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

:

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

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

This is basically the inverse of the control: not for the class itself, to decide how another class might want to compare its instances.

+2
source

Source: https://habr.com/ru/post/1628109/


All Articles