I am trying to compare two HashSets of objects by using .SetEquals(). I looked at some guides and saw that I needed to implement IEqualityComparer<> as part of the class in order for it to work properly. However, I have found that .SetEquals() is failing when I use it.
I have verified that the data I am attempting to compare is the same by using Lists and comparing them one element at a time. I am suspecting that I have implemented the IEqualityComparer<> incorrectly and it's using the default Equals() and GetHashCode().
Here's the code I am using:
public class MemberDataRow : IEqualityComparer<MemberDataRow>
{
public string ID { get; }
public string FirstName { get; }
public string MI { get; }
public string LastName { get; }
public decimal Premium { get; }
public string MemberCount { get; }
public string RateCell { get; }
public string RateCellDescription { get; }
public string Month { get; }
public bool Kickback { get; }
public decimal PrivateBalance { get; }
public decimal StateBalance { get; }
public decimal PrivateAssets { get; }
public decimal StateAssets { get; }
public decimal MUG { get; }
public DateTime Date { get; }
// Constructor Stuff is here. Removed for easier reading
bool IEqualityComparer<MemberDataRow>.Equals(MemberDataRow? x, MemberDataRow? y)
{
if ((x.ID == y.ID) &&
(x.FirstName == y.FirstName) &&
(x.MI == y.MI) &&
(x.LastName == y.LastName) &&
(x.Premium == y.Premium) &&
(x.MemberCount == y.MemberCount) &&
(x.RateCell == y.RateCell) &&
(x.RateCellDescription == y.RateCellDescription) &&
(x.Month == y.Month) &&
(x.Kickback == y.Kickback) &&
(x.PrivateBalance == y.PrivateBalance) &&
(x.PrivateAssets == y.PrivateAssets) &&
(x.StateBalance == y.StateBalance) &&
(x.StateAssets == y.StateAssets) &&
(x.MUG == y.MUG) &&
(x.Date == y.Date))
return true;
else
return false;
}
int IEqualityComparer<MemberDataRow>.GetHashCode(MemberDataRow obj)
{
// HashCode.Combine() only allows 7 arguments, so we have to chain them together.
return HashCode.Combine(
HashCode.Combine(obj.ID, obj.FirstName, obj.MI, obj.LastName, obj.Premium, obj.MemberCount, obj.RateCell),
HashCode.Combine(obj.RateCellDescription, obj.Month, obj.Kickback, obj.PrivateBalance, obj.PrivateAssets, obj.StateBalance),
HashCode.Combine(obj.StateAssets, obj.MUG, obj.Date));
}
}
I think what you want to do here is implement IEquatable<MemberDataRow>
. The interface that you're implementing now is meant to be implemented by a separate "comparer" class that you pass in the constructor of a HashSet
object instead.
See also here.