深入研究 ValueType.GetHashCode 的怪异之处:一个可能不变的值
围绕 ValueType.GetHashCode 的本机实现方式的阴谋() 计算值类型的哈希码是不可否认的。让我们通过检查特定示例及其意外结果来解开这个谜团。
考虑以下结构的两个实例:
struct TheKey { public int id; public string Name; }
为 Name 字段分配不同的值,我们期望它们的哈希代码不同。然而,输出揭示了一个惊人的现实:
var k1 = new TheKey(17, "abc"); var k2 = new TheKey(17, new string(new[] { 'a', 'b', 'c' })); Console.WriteLine("hash1={0}", k1.GetHashCode()); Console.WriteLine("hash2={0}", k2.GetHashCode()); // Output: // hash1=346948941 // hash2=346948941
尽管字符串引用不同,k1 和 k2 都产生相同的哈希代码。
揭开机制
ValueType.GetHashCode() 的本机实现通过一种极其复杂的机制进行操作。首先,它确定结构是否包含引用类型引用或字段间隙。如果这两个条件都不存在,它将对所有值的位执行有效的按位异或运算,从而有效地将所有字段组合到哈希码中。然而,这种方法并不普遍适用。
当存在引用类型或间隙时,代码会开始逐个字段遍历,搜索可用的字段 - 值类型或非空对象参考。一旦找到,该字段的哈希码与方法表指针进行异或,形成最终的哈希码。
揭开神秘面纱
在我们的示例中,可用字段恰好是 id。尽管字符串字段的值不同,但它会被忽略,导致 k1 和 k2 具有相同的 id,因此具有相同的哈希码。
结论
了解这种非常规行为增强了为哈希码计算精心设计值类型的重要性。避免仅仅依赖 CLR 的默认实现是至关重要的。通过显式定义哈希码计算,开发者可以确保其值类型的哈希码的唯一性和一致性。
以上是为什么结构体中的不同字符串引用会出现相同的 ValueType.GetHashCode() 结果?的详细内容。更多信息请关注PHP中文网其他相关文章!