作者:王大胖_wa_ngli | 来源:互联网 | 2023-01-11 03:48
我最近看到这个代码struct
,我想知道base.GetHashCode
实际上是做什么的.
public override int GetHashCode()
{
var hashCode = -592410294;
hashCode = hashCode * -1521134295 + base.GetHashCode();
hashCode = hashCode * -1521134295 + m_Value.GetHashCode();
return hashCode;
}
Jon Skeet..
7
coreclr repo有这样的评论:
行动:我们返回哈希码的算法有点复杂.我们寻找第一个非静态字段并获取它的哈希码.如果类型没有非静态字段,我们返回该类型的哈希码.我们不能获取静态成员的哈希码,因为如果该成员与原始类型的类型相同,我们将最终处于无限循环中.
但是,代码不存在,看起来并不完全是这样.样品:
using System;
struct Foo
{
public string x;
public string y;
}
class Test
{
static void Main()
{
Foo foo = new Foo();
foo.x = "x";
foo.y = "y";
Console.WriteLine(foo.GetHashCode());
Console.WriteLine("x".GetHashCode());
Console.WriteLine("y".GetHashCode());
}
}
我的盒子输出:
42119818
372029398
372029397
更改值y
似乎不会更改哈希码foo
.
但是,如果我们int
改为使用字段值,那么第一个字段会影响输出.
简而言之:这很复杂,您可能不应该依赖它在运行时的多个版本中保持不变.除非你真的非常确信你不需要将自定义结构用作基于散列的字典/集合中的键,否则我强烈建议覆盖GetHashCode
和Equals
(以及实现IEquatable
以避免装箱).
1> Jon Skeet..:
coreclr repo有这样的评论:
行动:我们返回哈希码的算法有点复杂.我们寻找第一个非静态字段并获取它的哈希码.如果类型没有非静态字段,我们返回该类型的哈希码.我们不能获取静态成员的哈希码,因为如果该成员与原始类型的类型相同,我们将最终处于无限循环中.
但是,代码不存在,看起来并不完全是这样.样品:
using System;
struct Foo
{
public string x;
public string y;
}
class Test
{
static void Main()
{
Foo foo = new Foo();
foo.x = "x";
foo.y = "y";
Console.WriteLine(foo.GetHashCode());
Console.WriteLine("x".GetHashCode());
Console.WriteLine("y".GetHashCode());
}
}
我的盒子输出:
42119818
372029398
372029397
更改值y
似乎不会更改哈希码foo
.
但是,如果我们int
改为使用字段值,那么第一个字段会影响输出.
简而言之:这很复杂,您可能不应该依赖它在运行时的多个版本中保持不变.除非你真的非常确信你不需要将自定义结构用作基于散列的字典/集合中的键,否则我强烈建议覆盖GetHashCode
和Equals
(以及实现IEquatable
以避免装箱).