在 C# 中实现 Equals 但不是 GetHashCode [重复]

Posted

技术标签:

【中文标题】在 C# 中实现 Equals 但不是 GetHashCode [重复]【英文标题】:implementing Equals but not GetHashCode in c# [duplicate] 【发布时间】:2012-05-17 21:24:59 【问题描述】:

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

我没有实现 Object 类的 GetHashCode 方法。所以我收到了一些警告。

有没有一种方法来检查相等性,我只检查 Equals 方法中的哈希码,因此同时实现 Equals 和 GetHashCode 而不会收到“Object.GetHashCode 未实现警告?”。

如果我只实现 Equals 而没有实现 GetHashCode 会发生什么? myclass 的实例在我的应用程序中是可更新的。

public class MyClass

private string x;
private string y;

public override bool Equals(object obj)
        

            try
            

                 return    Object.Equals(this.x, obj.x)
                        && Object.Equals(this.y, obj.y);

            
            catch(Exception Ex)
            
                log.Debug(Ex.StackTrace);
                throw; 
            
        


【问题讨论】:

***.com/questions/371328/… 回答最多吗?全部?这个的?可能重复? 顺便说一句,Equals 的实现太过分了;只需return this.x == other.x && this.y == other.y; 我来自 Java 世界。在 Java 中,我将引用与 == 进行了比较。尽管字符串在 c# 中是引用类型,但它们可以像值类型一样使用(使用 == 运算符),不像在 Java 中我会将值相等性与 str1.Equals(str2) 进行比较。特别是在这种情况下,如果我使用 this.str1 == this.str2 - 并且 str1 为 null,我想我会得到一个 NULL 指针异常? 【参考方案1】:

如果你实现了Equals 而不是GetHashCode,那么如果你的类用于任何使用散列的数据结构(HashSet<T>Dictionary<K,V> 等),它的行为就会不正确。即使您没有明确使用这些数据结构,它们也可能被某些代码使用(例如,一些 Linq 操作使用 HashSet),因此也更安全地覆盖 GetHashCode

【讨论】:

特别是使用 IEqualityComparer 实例的 Linq 方法需要正确的哈希码才能工作。据我所知,这是ExceptDistinctUnionIntersect【参考方案2】:

GetHashCode用于在has表中存储和检索对象,也就是判断对象是否相等的另一种方式。

如果您覆盖一个 (Equals) 而不是另一个 (GetHashCode),那么您在使用 GetHashCode 时可能会遇到不一致的行为(即,将您的对象放入一个实现为哈希表的集合中)与Equals() 相比。

您可能会喜欢阅读 this post by Eric Lippert 关于该主题的内容。

【讨论】:

【参考方案3】:

如果您不实现GetHashCode,当您的类用作字典或散列集等结构中的键时,您的类将表现异常。如果你想使用这些类型的结构,没有办法绕过它。从技术上讲,如果您远离这些,您的应用程序将正常工作,但这是一种糟糕的形式,任何使用您的类的人都会大吃一惊。

【讨论】:

以上是关于在 C# 中实现 Equals 但不是 GetHashCode [重复]的主要内容,如果未能解决你的问题,请参考以下文章

了解类型参数是不是在 c# 2.0 中实现接口的更简单方法是啥?

如何在 JPA 的 BaseEntity 中实现 equals() 和 hashcode() 方法?

在 C# 中实现 runas

如何在 C# 中实现单例设计模式? [复制]

在 C# 中实现功能标志

如何在 C# 中实现 glob