0

I have a lot of List comparison, checked using sequenceEqual:

this.Details.SequenceEqual<EventDetail>(event.Details, new DetailsEqualityComparer());

Since in this way I have a lot of boilerplate, writing tons of class pretty similar (except for the type parameter for Equals and getHashCode) named aClassEqualityComparer, anotherClassEqualityComparer and so on...

At this point, i have thinked to rewrite my comparer using generics in this way:

class GenericEqualityComparer<T> : IEqualityComparer<T> where T : class
{
    public bool Equals(T x, T y)
    {
        if (Object.ReferenceEquals(x, y)) return true;

        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return x.Equals(y);  // here comes the problems
    }

    public int GetHashCode(T obj)
    {
        // some hashing calculation
    }
}

The problem is: as far as I suppose in the Equals method, since the used Equals is the Object.Equals and I always get false.

Where is the error?

BAD_SEED
  • 4,840
  • 11
  • 53
  • 110

2 Answers2

4

Well, you could do:

return EqualityComparer<T>.Default.Equals(x, y);

and

return EqualityComparer<T>.Default.GetHashCode(x);

but that will still use reference equality unless Equals is overridden for T and/or T implements IEquatable<T> (which may be what you want, but it's not completely clear from your question).

In fact, that implementation would basically replicate EqualityComparer<T>.Default, so the use of your custom class is redundant - you can just use EqualityComparer<T>.Default directly without wrapping it.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • 1
    If he's already overridden these methods in the base type he doesn't need to create a new `EqualityComparer` that uses `EqualityComparer.Default`, he just needs to use `EqualityComparer.Default` without a wrapper. – Servy Jun 09 '14 at 16:50
  • @Servy Agreed - that's what I mean in the last senetence. I think you explained it more clearly, though. – D Stanley Jun 09 '14 at 16:52
1

You seem to reimplemented default equality comparer that calls instance's Equals and GetHashCode, which when not implemented by the class will indeed fall back to Object's implementation.

Possibly you want to pass comparer/hash code methods into your comparer:

class GenericEqualityComparer<T> : IEqualityComparer<T> where T : class
{
   Func<T,T,bool> myCompare;
   public GenericEqualityComparer<T>(
      Func<T,T,bool> myCompare, Func<T,int> myGetHashCode)
   {
      this.myCompare= myCompare;                 
       ...
   }

   public bool Equals(T x, T y)
   {
     ....
     return myCompare(T,T);
   }
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179