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