C# 带十进制字段的结构的Equals/GetHashCode契约冲突
我正在阅读以下问题及其答案---C# 带十进制字段的结构的Equals/GetHashCode契约冲突,c#,C#,我正在阅读以下问题及其答案--- ---这基本上表明了系统的GetHashCode的自然正确且通常高效的实现。其中一篇链接帖子中的答案简要说明GetHashCode在结构的十进制字段方面存在缺陷,例如: struct Test { public decimal value; } static void Main() { var d1 = 1.0m; var d2 = 1.00m; // Numerically equal but has different bits
系统的GetHashCode
的自然正确且通常高效的实现。其中一篇链接帖子中的答案简要说明GetHashCode在结构的十进制字段方面存在缺陷,例如:
struct Test { public decimal value; }
static void Main() {
var d1 = 1.0m;
var d2 = 1.00m; // Numerically equal but has different bits
var t1 = new Test() { value = d1 };
var t2 = new Test() { value = d2 };
Console.WriteLine(Equals(d1, d2)); // True
Console.WriteLine(d1.GetHashCode() == d2.GetHashCode()); // True
Console.WriteLine(Equals(t1, t2)); // True
Console.WriteLine(t1.GetHashCode() == t2.GetHashCode()); // False!
}
对于这个包含小数的结构,ValueType.GetHashCode
违反了等于
/GetHashCode
关系。明确地说,这是以下内容(来自的摘要):
两个相等的对象返回相等的哈希代码
现在,请注意(框架4.5)的文档:
如果当前实例和obj的字段都不是引用
类型,Equals方法对这两个类型执行逐字节比较
内存中的对象
所以这显然不是真的,这也被观察到了
我(修订)的问题:这是Equals
中的错误还是GetHashCode
中的错误?从其他帖子所说的来看,这个bug似乎出现在GetHashCode
中,但MSDN可能存在的文档缺陷使得它非常不清楚。这里还有更多错误。如果它确实使用了第一个非静态字段的哈希代码,那么如果您检查,d1.GetHashCode()==d2.GetHashCode()
,那么这不可能是真的(是的,我还通过对t2执行t1.value.GetHashCode()
进行了验证。这个“错误”您在问题中的一篇帖子中已经提到了。问题到底是什么?另外,GetHashCode的文档提到了值类型,与代码中的注释不同:-它说它使用值类型的所有字段计算哈希代码。这同样不能解释上面的区别。@rae1问题n这就是为什么t1.GetHashCode()==t2.GetHashCode()
返回false
,因此如果这不是一个损坏的GetHashCode实现(或者等于,如果值类型是不同的)。@LasseV.Karlsen基于此已经在GetHashCode
实现中报告为一个bug。