只是想让有人证实我的想法,我在 Foo 类中尝试了覆盖 Equals 和 GetHashCode 的不同组合:
class Foo
{
static int n;
public override bool Equals(object obj)
{
return true;
//return false;
}
public override int GetHashCode()
{
return 0;
//return n++;
}
}
然后测试结果显示:
static void Main(string[] args)
{
HashSet<Foo> set = new HashSet<Foo>();
Foo f1 = new Foo();
Foo f2 = new Foo();
Console.WriteLine(f1.Equals(f2));
set.Add(f1);
Console.WriteLine(set.Contains(f2));
Console.ReadLine();
}
- 当Equals为真时,Contains由GetHashCode决定;
- 当 Equals 为假时,Contains 始终为假。
所以 Contains 由 Equals 然后由 GetHashCode 确定,对吗?
最佳答案
反过来说。首先调用 GetHashCode()
。这用于提供哈希码(因此得名),用于确定对象在内部的存储位置。
不能保证哈希码是唯一的(此外,它会进一步减少)因此可能有多个对象存储有相同的哈希值(越多,性能越差,但这是另一回事)。因此,在找到可能的匹配项后,Equals
用于确认匹配项。
所以 Contains
首先依赖于 GetHashCode()
,然后依赖于 Equals()
。
这两者是协同工作的,这就是为什么如果你覆盖另一个,你必须总是覆盖一个,并且总是以这样一种方式覆盖你的 GetHashCode()
,任何两个对象都会相互考虑 Equal()
将具有相同的代码。
关于c# - C# HashSet 是否通过 Equals 然后通过 GetHashCode 检查重复项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34735282/