重写具有'dibs'的类型的Equals和GetHashCode

本文关键字:Equals GetHashCode 类型 重写 dibs | 更新日期: 2023-09-27 17:49:40

这个问题和Jon的回答让我意识到这个问题的存在,所以我很好奇,并启动了Visual Studio。


我遵循了MSDN页面的一个示例,然后创建了我自己的小示例。内容如下:

public class Person : IEquatable<Person>
{
    public string IdNumber { get; set; }
    public string Name { get; set; }
    public bool Equals(Person otherPerson)
    {
        if (IdNumber == otherPerson.IdNumber)
            return true;
        else
            return false;
    }
    public override bool Equals(object obj)
    {
        if (obj == null) 
            return base.Equals(obj);
        if (!(obj is Person))
            throw new InvalidCastException("The Object isn't of Type Person.");
        else
            return Equals(obj as Person);
    }
    public override int GetHashCode()
    {
        return IdNumber.GetHashCode();
    }
    public static bool operator ==(Person person1, Person person2)
    {
        return person1.Equals(person2);
    }
    public static bool operator !=(Person person1, Person person2)
    {
        return (!person1.Equals(person2));
    }
}

我有几个问题:

  1. 如果Equals方法在处理我的自定义相等方面做得很好,为什么我必须重写GetHashCode方法?

  2. 当比较下面的东西时,使用哪个比较器,等号还是GetHashCode?

.

static void Main(string[] args)
{
    Person sergio = new Person() { IdNumber = "1", Name = "Sergio" };
    Person lucille = new Person() { IdNumber = "2", Name = "Lucille" };
    List<Person> people = new List<Person>(){
        sergio,
        lucille
    };
    Person lucille2 = new Person() { IdNumber = "2", Name = "Lucille" };
    if (people.Contains(lucille2))
    {
        Console.WriteLine("Already exists.");
    }
    Console.ReadKey();
}
  • operator方法到底是做什么的?这看起来像是某种巫术的黑魔法。
  • 重写具有'dibs'的类型的Equals和GetHashCode

    如果Equals方法在处理我的自定义相等方面做得很好,为什么我必须重写GetHashCode方法?

    这允许您的类型在通过散列工作的集合中使用,例如作为Dictionary<T, U>中的键,或存储在HashSet<T>中。

    当比较下面类似的东西时,使用哪个比较器,Equals还是GetHashCode?

    GetHashCode不用于比较-仅用于哈希操作。总是使用等号

    操作符方法到底是做什么的?这看起来像是某种巫术的黑魔法。

    这允许您直接在您的类型的两个实例上使用==。如果没有这个,如果类型是一个类,您将通过引用进行比较,而不是通过类型中的值进行比较。

    GetHashCode的目的是平衡哈希表,而不是确定相等性。当查找哈希表的成员时,所检查的哈希桶由哈希码决定,然后对象是否在桶中由相等性决定。这就是为什么GetHashCode必须与相等一致。

    要了解更多细节,请参阅我的文章:

    http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

    GetHashCode和Equals是两个非常不同的东西。Equals决定相等。GetHashCode返回一个适合哈希映射的哈希码,但不保证相等。因此,在相等问题中,Equals将是决定相等的方法。

    GetHashCode用于散列集,例如Dictionary。当在字典中查找一个条目时,您将在哈希码上匹配条目,然后在Equals上匹配条目。

    GetHashCode仅在使用散列表时由MSDN 使用。

    如果你需要相等,你只关心相等。MSDN建议也实现GetHashCode,因为迟早你可能会在哈希类对象(哈希表,哈希映射等)中使用你的对象。

    假设对象有1000字节,你需要一个快速的方法来确定两个对象之间的相等性-你计算哈希键(通过GetHashCode)。如果键不匹配,则对象不同。如果它们确实匹配,您不能确定它们是否确实相等,您需要使用equal()来验证-这更昂贵。

    哈希表集合使用这个想法。