I implemented IEqualityComparer
and I was getting incorrect comparisons, not even watching the debugger passing through my Equals
method when being used by IEnumerable.Contains
method.
public struct CustomMailAddress : IEqualityComparer<CustomMailAddress>
{
public string Address { get; private set; }
public string DisplayName { get; private set; }
public bool IsFullAddress { get; private set; }
public CustomMailAddress(string address)
{
this.Address = address;
this.DisplayName = String.Empty;
this.IsFullAddress = address.IndexOf('@') >= 0;
}
public CustomMailAddress(MailAddress address)
{
this.Address = address.Address;
this.DisplayName = address.DisplayName;
this.IsFullAddress = true;
}
public bool Equals(CustomMailAddress x, CustomMailAddress y)
{
return x.IsFullAddress ? x.Address.EndsWith(y.Address) : y.Address.EndsWith(x.Address);
}
public int GetHashCode(CustomMailAddress obj)
{
return obj.Address.GetHashCode();
}
}
Based on the MSDN documentation :
Elements are compared to the specified value by using the default equality comparer, Default.
Which leads to:
The default instance of the EqualityComparer class for type T.
From my understanding, they say my own comparer will be used. But this returns false
:
bool isMatch = source.CollectedAddresses.Any(x => _validAddreses.Contains(x));
So, since it should return true
and the debugger wasn't stopping at my Equals
method I used the Contains
overload, getting my desired true
.
bool isMatch = source.CollectedAddresses.Any(x => _validAddreses.Contains(x, new CustomMailAddress()));
What am I missing? Wasn't it supposed to use the EqualityComparer
my CustomMailAddress
has "by default"?
From my understanding, they say my own comparer will be used.
They never said that. You have misunderstood. If your understanding were correct, they would have said something like, "if T
implements IEqualityComparer<T>
, an instance of T
is returned".
But think about it, how can IEqualityComparer<T>.Default
know how to return an instance of T
? You haven't guaranteed it any parameterless constructors or anything like that!
The "default equality comparer" actually calls the Equals
method of IEquatable<T>
, so I think you probably have mixed up the two interfaces. Your struct should implement IEquatable<T>
, not IEqualityComparer
.