如何为结构实现base.GetHashCode()?

Jon*_*len 4 c# struct hashcode

我最近看到这个代码struct,我想知道base.GetHashCode实际上是做什么的.

    public override int GetHashCode()
    {
        var hashCode = -592410294;
        hashCode = hashCode * -1521134295 + base.GetHashCode();
        hashCode = hashCode * -1521134295 + m_Value.GetHashCode();
        return hashCode;
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

我的盒子输出:

42119818
372029398
372029397
Run Code Online (Sandbox Code Playgroud)

更改值y似乎不会更改哈希码foo.

但是,如果我们int改为使用字段值,那么第一个字段会影响输出.

简而言之:这很复杂,您可能不应该依赖它在运行时的多个版本中保持不变.除非你真的非常确信你不需要将自定义结构用作基于散列的字典/集合中的键,否则我强烈建议覆盖GetHashCodeEquals(以及实现IEquatable<T>以避免装箱).