BAD_SEED
BAD_SEED

Reputation: 5056

Equality Comparer using generic

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?

Upvotes: 1

Views: 4186

Answers (2)

Alexei Levenkov
Alexei Levenkov

Reputation: 100537

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

Upvotes: 1

D Stanley
D Stanley

Reputation: 152556

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.

Upvotes: 5

Related Questions