可空类型的方法

Methods on Nullable types

有人可以解释为什么可以在 null 实例上调用方法吗?

int? num = null;

var s1 = num.ToString();
var s2 = num.HasValue;
var s3 = num.GetHashCode();
var s4 = num.GetValueOrDefault();

var s5 = num.Value; // InvalidOperationException
var s6 = num.GetType(); // NullReferenceException

我可以在调试模式下检查 numnull,那么 ToString 方法或 HasValue getter 怎么可能调用了 null 实例,但是对于 ValueGetType 是不可能的?它们是否都是 Nullable<> 类型的方法或属性?

我自然会期望 Value getter returns null 值,类似于 HasValue returns false .我也希望 GetType returns Nullable<int> 输入信息,或者 num is int?num is Nullable<int> 有效。为什么它不起作用?如何检查 num 是否为可空类型?

创建实例不会改变任何内容:

Nullable<int> num = new Nullable<int>();

幕后是什么?

Nullable<T> 有一点编译器的魔力,使它 看起来 就像有一个 null 值一样。但是没有。基本上,由于 Nullable<T> 是一个值类型,所以它不能以 null 开头。它的可空性取决于是否有值。这意味着您可以调用 HasValue(这很重要,因为这是编译器在您编写 num == null 时插入的内容)和其他不依赖于存在的值的方法。

具体几点:

  • ToString 是一种实现,其工作方式类似于 null 值在用于字符串连接时如何转换为字符串,即生成空字符串。你也真的不想 ToString 抛出。
  • GetHashCode 是将 Nullable<T> 作为字典中的键或将它们放入哈希集中所必需的。它也不应该抛出,所以它必须 return 在没有价值的时候有一些合理的东西。
  • documentation 解释了一些基本概念。

但是,禁止在没有值时访问该值。正如 and Marc Gravell ♦ 在评论中指出的那样,这就是调用 GetType:

时隐含发生的事情

It would seem logical that the compiler could just silently replace nullableValue.GetType() with typeof(SomeT?), but that would then mean that it always gives confusing answers when compared to

object obj = nullableValue;
Type type = obj.GetType()

You would expect this to work similarly, but obj.GetType() will always return either typeof(T) (not typeof(T?)), or throw a NullReferenceException because T? boxes to either a T or to null (and you can't ask a null what type it is)

编译器专门处理的构造映射或多或少如下:

num == null         → !num.HasValue
num != null         → num.HasValue
num = null          → num = new Nullable<int>()
num = 5             → num = new Nullable<int>(5)
(int) num           → num.Value
(object) num        → (object) num.Value         // if HasValue
                    → (object) null              // if !HasValue

对运算符有额外的支持,最重要的是具有不可空 Ts 的比较运算符和处理潜在 null 值的各种运算符,如 ??,但这就是要点

不是真正的答案,只是一个注释。你写:

I would naturally expect the Value getter returns null value

不! Nullable<T> 存在的真正原因是防止您在未先检查的情况下获得 null 值。