You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何相等的简单结构体实例返回不同的哈希码?

值类型Equals与GetHashCode的优化差异疑问

示例代码

using System;
using System.Globalization;

var d1 = new DateTime(2023, 2, 28, 0, 0, 0, DateTimeKind.Unspecified);
var d2 = new DateTime(2023, 2, 28, 0, 0, 0, DateTimeKind.Local);

var foo1 = new Foo { d = d1 };
var foo2 = new Foo { d = d2 };

Console.WriteLine($"d1.Equals(d2): {d1.Equals(d2)}");
Console.WriteLine($"d1.GetHashCode() == d2.GetHashCode(): {d1.GetHashCode() == d2.GetHashCode()}");
Console.WriteLine($"foo1.Equals(foo2): {foo1.Equals(foo2)}");
Console.WriteLine($"foo1.GetHashCode() == foo2.GetHashCode(): {foo1.GetHashCode() == foo2.GetHashCode()}");

struct Foo {
    public DateTime d;
}

运行输出

d1.Equals(d2): True
d1.GetHashCode() == d2.GetHashCode(): True
foo1.Equals(foo2): True
foo1.GetHashCode() == foo2.GetHashCode(): False

问题背景

DateTime自身的Equals和GetHashCode方法都会忽略Kind属性,所以d1与d2的Equals返回True,哈希值也相等。但包含DateTime的自定义值类型Foo,它的Equals方法返回符合预期的True,可GetHashCode却返回了不同的值。

推测这和.NET对值类型的优化有关:当值类型的所有字段都是8字节宽度时,GetHashCode可能直接通过内存比较的方式计算哈希值,而非调用字段自身重写的GetHashCode方法。

疑问

  • 这种基于内存比较的优化是否仅作用于GetHashCode,而不影响Equals方法?
  • 该问题是仅在DateTime场景下出现,还是具有普遍性?比如优化逻辑没有检查字段是否重写了Equals/GetHashCode方法,导致所有满足字段宽度条件的值类型都会出现这种不一致?

内容的提问来源于stack exchange,提问作者synek317

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:02:48