为什么Nullable <T> HasValue属性不会在Null上抛出NullReferenceException?

Nat*_*han 20 .net c#

请考虑以下代码:

DateTime? ndate = null;
Console.WriteLine(ndate.HasValue);
Run Code Online (Sandbox Code Playgroud)

我原本期望一个NullReferenceException,但HasValue确实会返回false.但是,由于ndate为null,属性调用如何成功,因为没有对象可以调用属性HasValue?

Ree*_*sey 42

从技术上讲,"ndate"不为null - 它是一个值类型,其值指定为null.

当你写作时DateTime?,这只是一个简写Nullable<DateTime>,这是一个结构.从技术上讲,这是无法为空的,因为它不是引用类型.

  • 我假设然后(ndate == null)通过重载运算符工作? (2认同)

CMS*_*CMS 7

Nullable<T>是一个结构,基本上它不能保持一个null值.

您的作业实际上被编译成如下所示的内容:

Nullable<DateTime> ndate = new Nullable<DateTime>();
Run Code Online (Sandbox Code Playgroud)

另一个例子,表达式:

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

将生成以下IL:

.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0)
IL_0000:  ldloca.s   V_0
IL_0002:  initobj    valuetype [mscorlib]System.Nullable`1<int32>
Run Code Online (Sandbox Code Playgroud)

initobj操作的调用,该操作将指定地址处的值类型的每个字段初始化为空引用或适当基元类型的0.

总之,这里发生的是默认的struct初始化.


Eri*_*ert 7

我原以为NullReferenceException

没有空引用被解除引用,因此不应该期望"NullReferenceException".可空的DateTime不是空引用.它是一个空值.

但是,由于ndate为null,属性调用如何成功,因为没有对象可以调用属性HasValue?

这个问题预示着一个错误的前提.有一个对象.可以为空的DateTime表示可以为空的DateTime的空值.该值是一个对象.

考虑你的代码:

DateTime? ndate = null; 
Console.WriteLine(ndate.HasValue); 
Run Code Online (Sandbox Code Playgroud)

这只是写一些逻辑上类似的东西的简短方法:

DateTime ndate = default(DateTime); 
bool ndateHasValue = false;
Console.WriteLine(ndateHasValue); 
Run Code Online (Sandbox Code Playgroud)

可空值类型只是编写代码的一种令人愉快的方式,这意味着"请将一个布尔值附加到这个跟踪它是否在逻辑上为空的东西".