c# - C# HashSet 是否通过 Equals 然后通过 GetHashCode 检查重复项?

标签 c# .net dictionary hashset

只是想让有人证实我的想法,我在 Foo 类中尝试了覆盖 EqualsGetHashCode 的不同组合:

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();
    }
  1. 当Equals为真时,Contains由GetHashCode决定;
  2. 当 Equals 为假时,Contains 始终为假。

所以 Contains 由 Equals 然后由 GetHashCode 确定,对吗?

最佳答案

反过来说。首先调用 GetHashCode()。这用于提供哈希码(因此得名),用于确定对象在内部的存储位置。

不能保证哈希码是唯一的(此外,它会进一步减少)因此可能有多个对象存储有相同的哈希值(越多,性能越差,但这是另一回事)。因此,在找到可能的匹配项后,Equals 用于确认匹配项。

所以 Contains 首先依赖于 GetHashCode(),然后依赖于 Equals()

这两者是协同工作的,这就是为什么如果你覆盖另一个,你必须总是覆盖一个,并且总是以这样一种方式覆盖你的 GetHashCode() ,任何两个对象都会相互考虑 Equal() 将具有相同的代码。

关于c# - C# HashSet 是否通过 Equals 然后通过 GetHashCode 检查重复项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34735282/

相关文章:

c# - 如何在 Entity Framework 中保存组合的(新的+修改的)分离实体?

c# - 使用反射获取基类的 protected 属性值

python - %s 正在添加新的字典项目

c# - ASP.NET MVC 5 验证 - 属性不同

c# - 带有背景图像的 WinForms 分层控件在滚动时导致撕裂

c# - 以记录作为参数调用 Oracle 存储过程

c# - .Net C# TcpClient/Socket HTTP 客户端性能/效率

python - 大小高效的字典(关联数组)实现

c# - 如何将数据从模态形式传输到主要形式? Xamarin.Forms

c# - ASP.NET Core 在 Controller 构造函数中访问 User.Identity