如何使用超过 8 个值的 System.HashCode.Combine?

Ray*_*Ray 7 c# hashcode gethashcode

.NET Standard 2.1 / .NET Core 3引入 System.HashCode了快速将字段和值组合为哈希码的功能,而无需关心底层实现。

但是,它仅提供Combine最多 8 个值的方法重载。如果我有一个包含 9 个值(3x3 矩阵)甚至 16 个值(4x4 矩阵)的类,我该怎么办?

我应该简单地将两个Combine调用相加,并在每个调用中传递尽可能多的值吗?

public override int GetHashCode()
    => HashCode.Combine(M11, M12, M13, M21, M22, M23, M31, M32) + HashCode.Combine(M33);
Run Code Online (Sandbox Code Playgroud)

看看来源,我不能完全争论这是否可能有我不知道的影响。

Ray*_*Ray 14

正如System.HashCode您实际链接自己文档中所述,简单地将连续Combine调用创建的哈希码相加并不是解决方案。

静态Combine方法最多只允许 8 个值是正确的,但这些似乎只是舒适的方法。要组合 8 个以上的值,您必须HashCode像这样实例化和使用它:

public override int GetHashCode()
{
    HashCode hash = new HashCode();
    hash.Add(M11);
    hash.Add(M12);
    hash.Add(M13);
    hash.Add(M21);
    hash.Add(M22);
    hash.Add(M23);
    hash.Add(M31);
    hash.Add(M32);
    hash.Add(M33);
    return hash.ToHashCode();
}
Run Code Online (Sandbox Code Playgroud)

这确实让我想知道为什么没有HashCode构造函数接受 aparams object[] values以便您可以在一行中完成所有这些,但可能有一些原因我没有很快想到这一点。

仍然比自己完成所有内部工作要好得多!:-)

  • 不仅是数组分配,还包括每个值类型的装箱。效率极低。 (6认同)
  • @Vlad我认为对装箱和数组分配的担忧是关于接受“params object[] 值”的构造函数,我在回答中提到了这一点,而不是对“HashCode.Add”的调用。 (4认同)
  • 它可能与分配数组有关,这*可能*会拖累性能。由于 .NET Core 更注重性能,我认为这就是原因。 (2认同)