【问题标题】:Using GetHashCode of IEqualityComparer the right way正确使用 IEqualityComparer 的 GetHashCode
【发布时间】:2021-06-22 12:37:09
【问题描述】:

当使用IEqualityComparer 比较集合中的对象时,我不确定以下哪种方法最好。

这里是实现:

class CarComparer : IEqualityComparer<Car>
{
    public bool Equals(Car x, Car y)
    {
        throw new NotImplementedException();
    }

    public int GetHashCode(Car car)
    {
        //
    }
}

这是我的两个GetHashCode 实现选项

    public int GetHashCode(Car row)
    {
        return HashCode.Combine(row.Name, row.Color , row.Size);
    }

或者,

    public int GetHashCode(Car row)
    {
        return row.GetHashCode();
    }

我不喜欢第一个,因为它降低了代码的可维护性,并且在资源方面可能更便宜。但是很多人都是这样用的。

我想稍后在 linq 函数中使用我的 CarComparer。像这样:

cars.Distinct(new CarComparer());

我应该使用哪一个?

这是一个基于意见的问题吗?

【问题讨论】:

  • 大概你正在实现一个IEqualityComparer&lt;Car&gt;,因为Car本身并没有按照你想要的方式实现GetHashCodeEquals(这基本上是你写一个@的唯一原因987654332@)。在这种情况下,Car.GetHashCode() 肯定不会做你想做的事,因此委托给它是没有意义的
  • 如果您想使用CarGetHashCodeEquals 的实现,则没有理由实现自定义IEqualityComparer&lt;Car&gt;。如果您需要自定义逻辑来比较您的对象,您应该实现该接口。所以覆盖 EqualsGetHashCode 然后。
  • @BorisDetry 恐怕您的评论无济于事。是否要使用CarGetHashCode 实现?如果你想使用它,你不需要自定义IEqualityComparer&lt;Car&gt;。如果您不想使用它,请不要调用它(在您的 IEqualityComparer&lt;Car&gt; 中)
  • @BorisDetry 为什么不在Car 类中覆盖EqualsGetHashCode?这样你就不需要IEqualityComparer&lt;Car&gt;
  • @BorisDetry 好吧,在 Car 的 GetHashCode() 方法中调用 this.GetHashCode() 会导致堆栈溢出……调用 base.GetHashCode() 与完全不覆盖它完全一样,这显然是没有意义的。

标签: c# linq hashcode comparable


【解决方案1】:

正确答案:

使用 LINQ 时,Equals 方法调用GetHashCode 时,并且仅当GetHashCode 的结果对于集合中的两个项目相等时。

所以GetHashCode 也必须被覆盖:

  public int GetHashCode(Car row)
{
    return HashCode.Combine(row.Name, row.Color , row.Size);
}

See full response here

【讨论】:

    猜你喜欢
    • 2017-05-20
    • 2011-08-20
    • 1970-01-01
    • 2014-11-08
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多