为什么我需要在C#中覆盖.Equals和GetHashCode


Why do I need to override the .Equals and GetHashCode in C#

本问题已经有最佳答案,请猛点这里访问。

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

我被告知我需要重写.equals方法,然后还要重写getHasCode方法。我的课程如下:

1
2
3
4
5
public class Students    {
    public int PersonId { get; set; }
    public string Name { get; set; }
    public int Age {get; set;}
}

有人能解释为什么我需要重写.equals和.gethashcode吗?还有人能给我举个例子吗?尤其是我对哈希代码不太确定。注意,我的个人ID是这个类的唯一编号。


您需要覆盖这两个选项,原因有很多。例如,哈希代码用于字典和哈希表。equals用于对数据结构(如contains方法)所做的任何比较。一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
public partial class myClass
{
  public override bool Equals(object obj)
  {
     return base.Equals(obj);
  }

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

对于hashcode,我应该这样做:

1
2
3
4
5
6
  public int GetHashCode()
  {
     return PersonId.GetHashCode() ^
            Name.GetHashCode() ^
            Age.GetHashCode();
  }


类是引用类型。当您创建两个对象并将它们存储在变量中时,您只存储对它们的引用。这意味着,如果尝试比较它们,您将只比较两个引用,如果它们指向堆上的同一对象,则这两个引用将相等。如果你想改变这种行为,你必须重写Equals。还有一些集合依赖于GetHashCode将元素存储在类树(或任何其他)结构中,这些结构需要对给定类的两个对象进行某种比较。这就是为什么如果需要定义的类在指定的环境下正确地行为,那么需要实现这些方法的原因。GetHashCode的一个典型实现是类字段的xor,在@no know for name's answer中给出。但是,由于在您的示例中personid是唯一的,您也可以使用它:

1
2
3
4
public int GetHashCode()
{
   return PersonId.GetHashCode();
}