C# HashSet 不使用定义的 IEqualityComparer<>

C# HashSet not using defined IEqualityComparer<>

我正在尝试使用 .SetEquals() 来比较对象的两个哈希集。我查看了一些指南,发现我需要将 IEqualityComparer<> 作为 class 的一部分来实现,以使其正常工作。但是,我发现 .SetEquals() 在我使用时失败了。

我已经通过使用列表并一次比较一个元素来验证我尝试比较的数据是相同的。我怀疑我错误地实现了 IEqualityComparer<>,它使用的是默认的 Equals() 和 GetHashCode()。

这是我使用的代码:

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

我想你想在这里做的是实现 IEquatable<MemberDataRow>。您现在实现的接口意味着由您传入 HashSet 对象的构造函数的单独“比较器”class 实现。

另见 here

如果您打算通过使用对象的每个 属性 来计算它们来定义 Equals 和 GetHashCode,您不妨切换到使用记录:

public record MemberDataRow(
  string ID,
  string FirstName,
  string MI,
  string LastName,
  decimal Premium,
  string MemberCount,
  string RateCell,
  string RateCellDescription,
  string Month,
  bool Kickback,
  decimal PrivateBalance,
  decimal StateBalance,
  decimal PrivateAssets,
  decimal StateAssets,
  decimal MUG, 
  DateTime Date
);

records 根据所有组成属性自动覆盖 Equals 和 GetHashCode,它们在声明时是不可变的,并且有很多 cleaner/less 可以输入。他们有一个构造函数,您可以调用它以紧凑的方式设置所有道具