为啥我们需要在对象模型项目中使用 GetHashCode() 函数? [复制]

Posted

技术标签:

【中文标题】为啥我们需要在对象模型项目中使用 GetHashCode() 函数? [复制]【英文标题】:Why do we need GetHashCode() function in the Object Model Project? [duplicate]为什么我们需要在对象模型项目中使用 GetHashCode() 函数? [复制] 【发布时间】:2012-06-21 16:07:59 【问题描述】:

可能重复:Why is it important to override GetHashCode when Equals method is overriden in C#?

我在Object Model 中查看以下课程,无法理解在Class 中添加GetHashCode() 的意义。

示例类

public class SampleClass


    public int ID  get; set; 
    public String Name  get; set; 
    public String SSN_Number  get; set; 

    public override bool Equals(Object obj)
    
        if (obj == null || GetType() != obj.GetType())
            return false;

        SampleClass cls = (SampleClass)obj;
        return (ID == cls.ID) &&
               (Name == cls.Name) &&
               (SSN_Number == cls.SSN_Number);
    

    public override int GetHashCode()
    
        return ID.GetHashCode() ^ Name.GetHashCode() ^ SSN_Number.GetHashCode();
    

假设我有一个Sample Class 对象列表,我想获得一个特定的索引。那么Equals()可以帮我拿到那条记录。为什么要使用GetHashCode()

【问题讨论】:

从马嘴里——blogs.msdn.com/b/ericlippert/archive/2011/02/28/… FWIW GetHashCode 的实现对我来说看起来很糟糕。请参阅@AngshumanAgarwal 提到的 Lippert 的博客 【参考方案1】:

您需要同时处理这两个问题,因为 GetHashCode() 被许多集合实现(如 Dictionary)与 Equals 方法一起使用。重要的是,如果您重写 Equals 的实现,那么您必须重写 GetHashCode,使得根据您的新实现相等的任何两个对象也必须返回相同的哈希码。

如果他们不这样做,那么他们将无法在 Dictionary 中正常工作。一般没有那么难。我经常这样做的一种方法是获取我用于相等的对象的属性,并将它们连接到一个 String 对象中,然后返回 String.GetHashCode。

String 有一个很好的 GetHashCode 实现,它为各种值返回范围广泛的整数,从而在稀疏集合中产生良好的传播。

【讨论】:

对于 Linq-to-objects 也很重要。 @spender 这通常是因为那些 LINQ 方法在内部使用 Dictionary 或 HashSet。 还有 ILookup...,但是,是的,一般依赖于 HashTable 式集合。【参考方案2】:

当您的自定义类覆盖Equals 时,必须提供对GetHashCode 的覆盖。如果您省略GetHashCode,您将收到编译器警告“A public type overrides System.Object.Equals but doesn't override System.Object.GetHashCode”。

GetHashCode 根据当前实例返回一个适合散列算法和数据结构(如散列表)的值。相同类型且相等的两个对象必须返回相同的哈希码,以确保 System.Collections.HashTableSystem.Collections.Generic.Dictionary<TKey, TValue> 的实例正常工作。

假设没有必要在您的自定义类中覆盖GetHashCode,那么基于哈希的集合将不得不使用基类'Object.GetHashCode,这可能不会为您的自定义类的所有实例提供正确的结果。

如果您观察您发布的代码,您的 Equals 方法会比较 IDNameSSN 用于 2 个实例返回相等结果 并且相同的属性被用于散列算法 (ID^Name^SSN) 在您的 GetHashCode 方法中。

【讨论】:

以上是关于为啥我们需要在对象模型项目中使用 GetHashCode() 函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在启用 ARC 的项目中不需要维护保留计数

为啥有 Mongoose 模型而不仅仅是模式/文档? [复制]

为啥我们不再需要在更高版本的 ASP.NET Core 中手动验证模型?

为啥我们需要再次拟合模型才能获得分数?

我为啥要使用 POCO?

为啥使用 Core Data 的人想要在同一个托管对象模型中使用多个持久存储?