【问题标题】:Why do I need to override the .Equals and GetHashCode in C# [duplicate]为什么我需要覆盖 C# 中的 .Equals 和 GetHashCode [重复]
【发布时间】:2013-08-11 04:36:31
【问题描述】:

我正在使用 Entity Framework 5。在我的 C# 代码中,我想比较两个对象是否相等。如果没有,那么我想发布更新。

有人告诉我我需要重写 .Equals 方法,然后还要重写 gethascode 方法。我的课程如下所示:

public class Students    {
    public int PersonId { get; set; }
    public string Name { get; set; }
    public int Age {get; set;} 
}

能否解释一下为什么我需要重写 .Equals 和 .GetHashCode。也有人可以给我一个例子。特别是我不确定哈希码。请注意,我的 PersonId 是此类的唯一编号。

【问题讨论】:

标签: c#


【解决方案1】:

出于多种原因,您需要重写这两种方法。例如,GetHashCode 用于在DictionaryHashTable 中进行插入和查找。 Equals 方法用于对象的任何相等测试。例如:

public partial class myClass
{
  public override bool Equals(object obj)
  {
     return base.Equals(obj);
  }

  public override int GetHashCode()
  {
     return base.GetHashCode();
  }
}

对于GetHashCode,我会这样做:

  public int GetHashCode()
  {
     return PersonId.GetHashCode() ^ 
            Name.GetHashCode() ^ 
            Age.GetHashCode();
  }

如果你覆盖GetHashCode 方法,你也应该覆盖Equals,反之亦然。如果在测试两个对象是否相等时,覆盖的 Equals 方法返回 true,则覆盖的 GetHashCode 方法必须为这两个对象返回相同的值。

【讨论】:

  • 我想他说的ID是唯一的^
  • 是的 ID 是唯一的。我可以将它用于哈希码吗?为什么我需要创建一个 GetHashCode。它是如何使用的?
  • @Melina 如果您正在使用哈希表、字典或其他一些东西,则调用 GetHashCode 来获取类的哈希。您只能从 id 进行散列,但这是您的选择,我会对所有成员进行散列,但如果 ID 确实是唯一的,这不是强制性的
  • 谢谢,但我一直听到“如果我覆盖 .Equals”,我需要覆盖 GetHashCode。所以如果我通常不覆盖 .Equals 我还需要覆盖 .GetHashCode 吗?
  • @Melina 如果您不覆盖 Equals,并且不打算使用字典、列表或其他数据结构并且不需要比较不同的类型,那么您可能不需要覆盖这两者, 否则你应该,如果你覆盖等号,你肯定应该覆盖 hashCode
【解决方案2】:

类是引用类型。当您创建两个对象并将它们存储在变量中时,您只是存储对它们的引用。这意味着如果您尝试比较它们,您只会比较两个引用,只有当它们指向堆上的同一个对象时它们才会相等。如果你想改变这种行为,你必须覆盖Equals
还有一些集合依赖GetHashCode 将元素存储在树状(或任何其他)结构中,这些结构需要在给定类的两个对象之间进行比较。如果您需要定义的类在指定情况下正确运行,这就是为什么您需要实现这些方法的原因。
GetHashCode 的典型实现是类字段的异或,在@No Idea For Name 的答案中给出。但由于 PersonId 在您的示例中是唯一的,您也可以使用它:

public int GetHashCode()
{
   return PersonId.GetHashCode();
}

【讨论】:

  • 谢谢。现在我明白了。至于GetHashCode。为什么需要它?当我的 ID 是唯一的时,您如何建议我应该对其进行编码?
  • @Melina,同样的原因。 GetHashCode(用于对象)的默认实现基于引用比较。作为一项规则,GetHashCode 应该表现出与Equals 相同的行为(尽管存在哈希冲突)。
  • @Melina 您只需返回 PersonId 的哈希码。而且我相信我已经解释了为什么它必须被覆盖。如果仍不清楚,请具体说明。
猜你喜欢
  • 1970-01-01
  • 2012-03-08
  • 2019-01-22
相关资源
最近更新 更多