2

这个问题和 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. 在比较类似下面的内容时,使用哪个比较器,Equals 还是 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();
}
  1. 运算符方法到底是做什么的?看起来那里正在发生某种伏都教黑魔法。
4

4 回答 4

7

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

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

在比较类似下面的内容时,使用哪个比较器,Equals 还是 GetHashCode?

GetHashCode 不用于比较 - 仅用于散列操作。始终使用等于。

运算符方法到底是做什么的?看起来那里正在发生某种伏都教黑魔法。

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

于 2011-04-09T22:14:52.410 回答
3

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

有关详细信息,请参阅我关于该主题的文章:

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

于 2011-04-09T22:15:10.210 回答
1

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

GetHashCode适用于哈希集,例如Dictionary. 在字典中查找项目时,您将匹配哈希码上的条目,然后在Equals.

于 2011-04-09T22:14:07.833 回答
0

当您使用哈希表时,MSDN 才使用 GetHashCode 。

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

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

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

于 2011-04-09T22:26:25.637 回答