在C#中实现Equals但不实现GetHashCode

3

可能是重复问题:
为什么在C#中重写Equals方法时重写GetHashCode方法很重要?

我没有实现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; 
            }
        }

}

2
https://dev59.com/yXRC5IYBdhLWcg3wOeSB#371348 这个回答是否解答了大部分还是全部的相关问题?有可能是重复问题吗? - Marc Gravell
1
顺便说一句,那个“Equals”实现过于复杂了;只需要写成“return this.x == other.x && this.y == other.y;”就可以了。 - Marc Gravell
我来自Java世界。在Java中,我使用“==”比较引用。虽然在c#中字符串是引用类型,但可以像值类型一样使用(使用“==”运算符),不像在Java中我要使用str1.Equals(str2)来比较值的相等性。特别是在这种情况下,如果我使用this.str1 == this.str2 ,而str1为空,我认为会得到一个空指针异常? - Utpal Mattoo
3个回答

3
如果你实现了 `Equals`,但没有实现 `GetHashCode`,那么如果你的类被用在任何使用哈希的数据结构中 (如 `HashSet`、 `Dictionary` 等)它将会表现不正确。即使你没有明确使用这些数据结构,有可能一些代码会使用它们(例如,一些 Linq 操作会使用 HashSets),因此最好也重写 `GetHashCode` 方法。

特别是使用IEqualityComparer实例的Linq方法需要正确的哈希码才能正常工作。据我所知,这些方法包括ExceptDistinctUnionIntersect - MakePeaceGreatAgain

2

GetHashCode被用于在哈希表中存储和检索对象,也就是另一种判断对象相等性的方法。

如果你重写了一个方法(Equals)而没有重写另一个方法(GetHashCode), 那么当使用GetHashCode(即将你的对象放入实现为哈希表的集合中)时与使用Equals()时,可能会遇到不一致的行为。

你可以阅读Eric Lippert所写的有关此主题的文章


1
如果您不实现GetHashCode,那么当您的类被用作字典或哈希集等结构中的键时,它将表现得不稳定。如果您想使用这些类型的结构,那就没有其他办法了。从技术上讲,如果您避开这些结构,您的应用程序仍然可以工作,但这是不好的形式,任何使用您的类的其他人都会感到惊讶。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接