编辑:现已发布。现在,推荐的创建哈希码的方式是这样的:System.HashCode
public override int GetHashCode()
{
return HashCode.Combine(fieldA, fieldB, fieldC);
}
System.HashCode.Combine()
将在内部调用每个字段,并自动执行正确的操作。.GetHashCode()
对于非常多的字段(超过 8 个),您可以创建一个实例,然后使用方法:HashCode
.Add()
public override int GetHashCode()
{
HashCode hash = new HashCode();
hash.Add(fieldA);
hash.Add(fieldB);
hash.Add(fieldC);
hash.Add(fieldD);
hash.Add(fieldE);
hash.Add(fieldF);
hash.Add(fieldG);
hash.Add(fieldH);
hash.Add(fieldI);
return hash.ToHashCode();
}
Visual Studio 2019现在有一个快速操作助手,可以为您生成Equals()
和GetHashCode()。
只需右键单击声明中的类名>快速操作和重构>生成等于和 GetHashCode。选择希望它用于相等的成员,然后选择“实现 IEqualable”,然后单击“确定”。
最后一件事:如果您需要获取对象的结构哈希代码,例如,如果要包含根据其内容(也称为结构)而不是其引用而变化的数组的哈希代码,则需要将字段转换为并手动获取其哈希代码,如下所示:IStructuralEquatable
public override int GetHashCode()
{
return HashCode.Combine(
fieldA,
((IStructuralEquatable)stringArrayFieldB).GetHashCode(EqualityComparer<string>.Default));
}
这是因为接口几乎总是显式实现的,因此需要强制转换为调用而不是默认方法。IStructuralEquatable
IStructuralEquatable
IStructuralEquatable.GetHashCode()
object.GetHashCode()
最后,在当前实现中,an 只是整数值本身,因此传入哈希码值而不是字段本身对结果没有影响。.GetHashCode
int
HashCode.Combine()
旧答案:
为了完整起见,下面是从 .NET 元组引用源第 52 行获取的哈希算法。有趣的是,这个哈希算法是从System.Web.Util.HashCodeCombiner
复制过来的。
代码如下:
public override int GetHashCode() {
// hashing method taken from .NET Tuple reference
// expand this out to however many items you need to hash
return CombineHashCodes(this.item1.GetHashCode(), this.item2.GetHashCode(), this.item3.GetHashCode());
}
internal static int CombineHashCodes(int h1, int h2) {
// this is where the magic happens
return (((h1 << 5) + h1) ^ h2);
}
internal static int CombineHashCodes(int h1, int h2, int h3) {
return CombineHashCodes(CombineHashCodes(h1, h2), h3);
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4) {
return CombineHashCodes(CombineHashCodes(h1, h2), CombineHashCodes(h3, h4));
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) {
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), h5);
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) {
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6));
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) {
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7));
}
internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) {
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8));
}
当然,实际的元组(实际上是一个)有一个大块,可以根据它所包含的项目数来决定调用其中哪一个 - 你自己的代码可能不需要它。GetHashCode()
Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
switch