给定以下类
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();
}
}
我已经覆盖了该方法,因为表示 s 表的一行。覆盖 ?Equals
Foo
Foo
GetHashCode
为什么覆盖很重要?GetHashCode
网友回答:
实际上很难正确实现,因为除了 Marc 已经提到的规则之外,哈希代码在对象的生命周期内不应更改。因此,用于计算哈希代码的字段必须是不可变的。GetHashCode()
当我与NHibernate合作时,我终于找到了这个问题的解决方案。
我的方法是根据对象的 ID 计算哈希代码。ID 只能通过构造函数设置,因此如果您想更改 ID(这不太可能),您必须创建一个具有新 ID 的新对象,因此需要一个新的哈希代码。此方法最适合 GUID,因为可以提供随机生成 ID 的无参数构造函数。
网友回答:
是的,如果您的项目将用作字典中的键,或者等,这很重要 – 因为这用于(在没有自定义的情况下)将项目分组到存储桶中。如果两个项目的哈希码不匹配,则它们可能永远不会被视为相等(永远不会调用 Equals)。HashSet<T>
IEqualityComparer<T>
GetHashCode() 方法应该反映逻辑;规则是:Equals
Equals(...) == true
GetHashCode()
GetHashCode()
Equals
在这种情况下,看起来 “” 是一个合适的实现。如果要测试多个属性,通常使用如下所示的代码将它们组合在一起,以减少对角线冲突(即具有不同的哈希代码):return FooId;
GetHashCode()
new Foo(3,5)
new Foo(5,3)
在现代框架中,该类型具有帮助您从多个值创建哈希代码的方法;在较旧的框架上,你需要没有,所以像这样:HashCode
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
这里演示了当你弄错时会发生什么。
网友回答:
通过覆盖等于,您基本上表明您更知道如何比较给定类型的两个实例。
下面你可以看到ReSharper如何为你编写GetHashCode()函数的例子。请注意,此代码段旨在由程序员进行调整:
public override int GetHashCode()
{
unchecked
{
var result = 0;
result = (result * 397) ^ m_someVar1;
result = (result * 397) ^ m_someVar2;
result = (result * 397) ^ m_someVar3;
result = (result * 397) ^ m_someVar4;
return result;
}
}
如您所见,它只是尝试根据类中的所有字段猜测一个好的哈希代码,但是如果您知道对象的域或值范围,您仍然可以提供更好的哈希代码。
模板简介:该模板名称为【为什么在覆盖等于方法时重写 GetHashCode 很重要?】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。