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

Dav*_*ish 38 c# nullable

有点奇怪的问题......

但是,任何人都可以给我一个理由,说明为什么这会是预期的行为?

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

//Makes perfect sense
object o = null;
o.GetHashCode().Dump();
Run Code Online (Sandbox Code Playgroud)

NullReferenceException:未将对象引用设置为对象的实例.

//Seems very odd
int? i = null;
i.GetHashCode().Dump();
Run Code Online (Sandbox Code Playgroud)

0

这显然意味着:

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

zero.GetHashCode() == argh.GetHashCode(); //true
Run Code Online (Sandbox Code Playgroud)

Chr*_*Fin 46

这里的重点是

int? i = null;
Run Code Online (Sandbox Code Playgroud)

不创建一个变量i,其是null,但(通过执行隐式转换)一个Nullable<int>不具有一个值的实例.
这意味着对象/实例不是null(并且Nullable<T>它实际上不是结构/值类型null),因此必须返回哈希代码.

这也记录在这里:

如果HasValue属性为true,则Value属性返回的对象的哈希码,如果HasValue属性为false,则返回零.

  • 你可能想解释一下,因为`Nullable`是一个值类型...... (4认同)

Joh*_*ica 14

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

因为Nullable实际上是一个结构(它不能为null),所以它必须为哈希代码返回一些东西,通常它会返回值的哈希码(大概是为了尽可能透明到其中的值).当值为null时,硬编码默认返回0:

public override int GetHashCode() {
    return hasValue ? value.GetHashCode() : 0;
}
Run Code Online (Sandbox Code Playgroud)

看到这里.

  • 如果它抛出了NullReferenceException并且你有一个`HashSet <int?>`.您无法为其添加空值.你会得到一个NullReferenceExeption.这不是真正预期的行为 - 如果它不能接受空值,为什么要使用HashSet <int?>?您只需使用HashSet <int>.[实施例](https://dotnetfiddle.net/Jfhu8G).如果它不抛出异常并且更符合使用Nullable,恕我直言的想法,它在一般框架中更有意义. (10认同)
  • @john,当你将`null`添加到`HashSet <string>`时会发生什么? (4认同)
  • 因此,它是否抛出NullReferenceException是无关紧要的,否则它将在null字符串的情况下失败. (3认同)
  • 它可能抛出相同的NullReferenceException,而不是 - 哪个IMO会更正确, (2认同)

gab*_*bba 8

它看起来像的记录的行为Nullable<T>.GetHashCode(),如文档说:

如果HasValue属性为true,则Value属性返回的对象的哈希码,如果HasValue属性为false,则返回零.