CLR 如何在为结构分配 null 值时绕过引发错误
本文关键字:错误 null 分配 结构 CLR | 更新日期: 2023-09-27 18:36:03
我试图理解这段代码中的一件事:
Nullable<Int32> x = 5;
Nullable<Int32> y = null;
Console.WriteLine("x: HasValue={0}, Value={1}", x.HasValue, x.Value);
Console.WriteLine("y: HasValue={0}, Value={1}", y.HasValue, y.GetValueOrDefault());
输出为:
x: HasValue=True, Value=5
y: HasValue=False, Value=0
当你把null
传递给y
时,我不明白的事情,我相信它调用public static implicit operator Nullable<T>(T value)
但是此方法的定义初始化了一个新的结构传递value
,该结构被分配null
但是构造函数方法不检查它是否为null,因此它可以default(T)
分配给value
。
为什么我们甚至可以在这里将 null 分配给结构并且它工作正常?
你们能知道我在这里错过了什么吗?我不明白它是如何绕过null
并返回默认值的。
可为空的代码内部定义:
http://codepaste.net/gtce6d
相信它调用公共静态隐式运算符 Nullable(T 值)
不,它没有,因为在这种情况下T
Int32
,而null
不是Int32
。它只是将y
变量保留为默认值,这意味着对于结构来说,所有字节都0
。这将导致结构具有返回false
的HasValue
。
您不能真正将null
传递给结构,但 C# 编译器正在将其转换为默认初始化。
默认值在new Nullable<T>(value);
调用的构造函数中分配(第 40 行)
我的猜测是,将null
分配给可为空的会调用默认构造函数。这是hasValue
保持false
的唯一可能方式。
Nullable<T>
只是一个结构,它有一个布尔字段指示它是否有值,还有一个字段(如果第一个字段为真)指示该值是什么。 实际上不可能将任何结构设置为null
,Nullable<T>
也不例外。 相反,编译器将设置Nullable<T>
的请求转换为null
的请求,将"具有值"字段(反映在属性HasValue
中)设置为 false,并将"实际值"字段(反映在属性Value
中)设置为其类型的默认值。
就我个人而言,我认为假装HasValue
是假的Nullable<T>
是null
更令人困惑而不是有用,但我并不Microsoft。 我认为每个Nullable<T>
类型都有一个静态属性Nullable<T>.Null
会更有帮助(这相当于default(Nullable<T>)
,但是Nullable<T>
的行为已经足够完善,我怀疑它永远不会改变。