Reputation: 5056
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
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
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