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

C# 如何为结构实现base.GetHashCode()?,c#,struct,hashcode,C#,Struct,Hashcode,我最近在一个struct中看到了这段代码,我想知道base.GetHashCode实际上做了什么 public override int GetHashCode() { var hashCode = -592410294; hashCode = hashCode * -1521134295 + base.GetHashCode(); hashCode = hashCode * -1521134295 + m_Value.GetHas

我最近在一个
struct
中看到了这段代码,我想知道
base.GetHashCode
实际上做了什么

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

结构的基类是
ValueType
类,源代码是在线的。他们很有帮助地留下了一条评论,描述了它的工作原理:

:

CORECRL回购协议有:

措施:我们返回哈希代码的算法有点复杂。我们看 对于第一个非静态字段,获取其哈希代码。如果类型没有 非静态字段,则返回类型的哈希代码。我们不能坐飞机 静态成员的哈希代码,因为如果该成员与 原始类型,我们将在一个无限循环中结束

然而,代码不在那里,看起来情况并非如此。样本:

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
,以避免装箱).

我假设他指的是声明
公共结构X
时继承的基本GetHashCode,这可能是所有人的一个实现。@LasseVågsætherKarlsen哦,当然,谢谢!我已经更新了答案。使用ints显示值发生了变化,所以是的,这很复杂,但这也是为什么它是未记录的行为。似乎当涉及ints(至少)时,使用的字段gethashcodes/值有一个简单的XOR,如果一个字段=24,另一个字段是8,第三个字段是16,然后,最终结果与我在其中放入任何其他值的结果相同,这些值加起来等于XOR到0。@LasseVågsætherKarlsen:啊,我需要更正我的答案-我只看到第一个字段会影响事情。@LasseVågsætherKarlsen:编辑。看看你是否认为我还有什么需要修改的地方。不,我的评论只是观察性的,当我发现参考源不具有代表性时,我又回到了文档中,文档中没有明确说明这是如何实现的,只是一个模糊的描述。
42119818
372029398
372029397