为什么 `null` Nullable<T> 有哈希码?

Why does a `null` Nullable<T> have a hash code?

有点奇怪的问题...

但是谁能给我解释为什么这是预期的行为?

这对我来说似乎很奇怪....

//Makes perfect sense
object o = null;
o.GetHashCode().Dump();

NullReferenceException: Object reference not set to an instance of an object.

//Seems very odd
int? i = null;
i.GetHashCode().Dump();

0

这显然意味着:

int? zero = 0;
int? argh = null;

zero.GetHashCode() == argh.GetHashCode(); //true

这里的重点是

int? i = null;

不会创建变量 i,它是 null,而是(通过执行隐式转换)创建一个没有值的 Nullable<int> 实例。
这意味着 object/instance 不是 null(因为 Nullable<T> 是 struct/value 类型,它实际上不能是 null)因此必须 return 一个哈希码。

这也记录在案 here:

The hash code of the object returned by the Value property if the HasValue property is true, or zero if the HasValue property is false.

int? 实际上只是 shorthand for Nullable<int>,一个包装 int 类型以允许它为 null 的结构。 Nullable 可以与任何值类型一起使用。

因为 Nullable 实际上是一个结构体(它不能为 null),它必须 return something 作为哈希码,通常它会 return 值的哈希码(大概是为了对其中的值尽可能透明)。当值为null时,默认硬编码为return0:

public override int GetHashCode() {
    return hasValue ? value.GetHashCode() : 0;
}

here

它看起来像是 Nullable<T>.GetHashCode()as documentation says:

的记录行为

The hash code of the object returned by the Value property if the HasValue property is true, or zero if the HasValue property is false.