可空类型的方法

时间:2019-02-05 10:25:56

标签: c# nullable

有人可以解释为什么可以在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

我可以在调试模式下检查num是否为null,那么如何在{{1}上调用ToString方法或HasValue getter }实例,但是对于nullValue是不可能的吗?它们都是GetType类型的方法或属性吗?

我自然希望Nullable<>的getter返回Value的值,与null返回的HasValue类似。我也希望false返回GetType类型信息,或者Nullable<int>num is int?都能正常工作。为什么不起作用?如何检查num is Nullable<int>是可为空的类型?

创建实例不会对此进行任何更改:

num

幕后是什么?

2 个答案:

答案 0 :(得分:7)

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

关于一些具体点:

  • ToString是一种实现,类似于在字符串连接中使用null值将其转换为字符串时的工作方式,即产生空字符串。您也不希望ToString扔过。
  • GetHashCode对于将Nullable<T>作为字典中的关键字或放入哈希集中是必要的。它也不应抛出,因此它必须在没有值的情况下返回明智的信息。
  • documentation解释了一些基本概念。

但是,如果没有值,则禁止访问该值。正如注释中的Zohar PeledMarc Gravell ♦所注,这是调用GetType时隐式发生的情况:

  

看起来编译器可以用nullableValue.GetType()静默替换typeof(SomeT?)似乎是合乎逻辑的,但这意味着与

相比,它总是给出令人困惑的答案。
object obj = nullableValue;
Type type = obj.GetType()
     

您希望它的工作原理类似,但是obj.GetType()将始终返回typeof(T)(而不是typeof(T?))或抛出NullReferenceException,因为T?Tnull(您不能问null是什么类型)

编译器专门处理的结构的映射更多地是以下内容:

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

对运算符提供了额外的支持,最重要的是将比较运算符与不可为空的T进行比较,以及对诸如null之类的潜在??值进行运算的各种运算符,但这就是要点

答案 1 :(得分:0)

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

  

我自然希望Value的getter返回null的值

不! Nullable<T>存在的根本原因是为了保护您无需先检查即可获取null值。