鉴于以下课程
public class Foo { public int FooId { get; set; } public string FooName { get; set; } public override bool Equals(object obj) { Foo fooItem = obj as Foo; if (fooItem == null) { return false; } return fooItem.FooId == this.FooId; } public override int GetHashCode() { // Which is preferred? return base.GetHashCode(); //return this.FooId.GetHashCode(); } }
我重写了该Equals方法,因为Foo代表Foos表的一行。哪种方法可以覆盖GetHashCode?
Equals
Foo
GetHashCode
为什么覆盖很重要GetHashCode?
是的,将您的项目用作字典或HashSet<T>等等中的键非常重要- 因为它用于(在没有custom的情况下IEqualityComparer<T>)将项目分组到存储桶中。如果两个项目的哈希码不匹配,则可能 永远不会 认为它们相等(永远不会调用等于)。
HashSet<T>
IEqualityComparer<T>
所述的GetHashCode()方法应该反映Equals逻辑; 规则是:
Equals(...) == true
GetHashCode()
在这种情况下,看起来“ return FooId;”是合适的GetHashCode()实现。如果您要测试多个属性,通常使用如下代码将它们组合在一起,以减少对角线冲突(即,new Foo(3,5)与的哈希码不同new Foo(5,3)):
return FooId;
new Foo(3,5)
new Foo(5,3)
unchecked // only needed if you're compiling with arithmetic checks enabled { // (the default compiler behaviour is *disabled*, so most folks won't need this) int hash = 13; hash = (hash * 7) + field1.GetHashCode(); hash = (hash * 7) + field2.GetHashCode(); ... return hash; }
哦,为方便起见,在覆盖和时,您也可以考虑提供==和!=运算符。Equals``GetHashCode
==
!=
Equals``GetHashCode
当你得到这个错误会发生什么情况的演示是在这里。