为啥我需要覆盖 C# 中的 .Equals 和 GetHashCode [重复]
Posted
技术标签:
【中文标题】为啥我需要覆盖 C# 中的 .Equals 和 GetHashCode [重复]【英文标题】: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 是此类的唯一编号。
【问题讨论】:
***.com/questions/371328/… @Melina 您在 cmets 中多次询问为什么需要覆盖GetHashCode
。请阅读@CodeIgnoto 链接到的问题的答案。
【参考方案1】:
出于多种原因,您需要重写这两种方法。例如,GetHashCode
用于在Dictionary
和HashTable
中进行插入和查找。 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 的哈希码。而且我相信我已经解释了为什么它必须被覆盖。如果仍不清楚,请具体说明。以上是关于为啥我需要覆盖 C# 中的 .Equals 和 GetHashCode [重复]的主要内容,如果未能解决你的问题,请参考以下文章
为啥我需要覆盖 Java 中的 equals 和 hashCode 方法?
为啥 StringBuffer/StringBuilder 不覆盖 equals 或 hashCode?
来自 C# 的 mingw DLL:为啥我必须覆盖新/删除?
为啥 set.contains 不使用覆盖的 equals() 方法?