为什么这个简单的结构体为相等的对象返回不同的哈希码?

syn*_*317 8 .net c# .net-core

快速示例:

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;
}
Run Code Online (Sandbox Code Playgroud)

印刷:

d1.Equals(d2): True
d1.GetHashCode() == d2.GetHashCode(): True
foo1.Equals(foo2): True
foo1.GetHashCode() == foo2.GetHashCode(): False
Run Code Online (Sandbox Code Playgroud)

游乐场,net7

DateTime故意忽略KindEqualsGetHashCode方法。然而,似乎在GetHashCode包含 的简单结构的方法中它并没有被忽略DateTime

我的猜测是,这可能与此优化有关,该优化memcmp在所有字段均为 8 字节宽时使用(例如此处讨论)。

但是,有没有可能它只用于GetHashCode而不用于Equals?它是“唯一”的问题DateTime还是更普遍的问题,例如此优化不检查覆盖Equals/ GetHashCode