C# 为什么Object.ReferenceEquals(可为null的原语的null)为true?

C# 为什么Object.ReferenceEquals(可为null的原语的null)为true?,c#,reference,nullable,C#,Reference,Nullable,所以我们可以有可为空的基元类型 bool? x = null; 这很好。但我的理解一直是,它实际上不是一个null引用 这是可能的 我一直认为nullables是带有操作符和Equals重载的类或结构,但今天我检查了一下 Object.ReferenceEquals(null, x); //true 我不知道这是怎么回事 它怎么可能同时是一个指向null的引用,并且具有可调用的非扩展属性 如果这是一个编译器技巧,有人知道它的具体功能吗?null可空值被装箱到空引用。null是一个结构,并且x

所以我们可以有可为空的基元类型

bool? x = null;
这很好。但我的理解一直是,它实际上不是一个
null
引用

这是可能的

我一直认为nullables是带有操作符和Equals重载的类或结构,但今天我检查了一下

Object.ReferenceEquals(null, x); //true
我不知道这是怎么回事

它怎么可能同时是一个指向
null
的引用,并且具有可调用的非扩展属性


如果这是一个编译器技巧,有人知道它的具体功能吗?

null
可空值被装箱到空引用。
null
是一个结构,并且
x.HasValue
不涉及装箱,只直接访问
HasValue
字段。调用
object.ReferenceEquals
时,
x
被装箱,因为这两个参数都是
object
,这是一种引用类型。
bool
bool?
都是结构,但它们确实继承自
object
。将结构赋给类型为
object
的变量会导致装箱-
bool
将装箱到包含bool的非空值
bool?
如果
HasValue
为false,或者如果
HasValue
为true,则将值装箱为
null
。有关详细信息,请参见本规范第4.3.1节“装箱转换”。@GeorgeMauer:您困惑的根源是对“继承自”的含义不清楚。继承自意味着基类型的某些成员也是派生类型的成员。这就是它的全部含义
Object
有一个方法
ToString
。它是可继承的成员。因此,从
对象继承的任何类型也有一个成员
ToString
。继承还意味着一种可转换关系,但这种可转换关系不需要保持表示。实际上,任何装箱转换都不是正确的。更具体地说:
ToString()
object
上的一个虚拟方法,它被
Nullable
覆盖。因此,当您调用
x.ToString()
时,您可以将其视为实际实现为
Nullable.ToString(ref x)
,其中参数是给定给
ToString
的“this”,因此
ToString
的实现在未装箱的值上运行。但是
GetType
不是虚拟的,因此您可以将其视为
object.GetType((object)x)
,因为同样,我们需要
this
object
。这就是拳击,嘿,它是零的!
Object.ReferenceEquals(null, x); //true