将可空类型与null进行比较

4
基本上,Nullable<T>是一个结构体,它解释了调用.HasValue永远不会抛出NullReferenceException的事情。我想知道为什么——即使使用Object.ReferenceEquals,对于没有值的可空类型进行与null的比较始终为true,因为它是一个结构体,所以我认为应该返回false。
CLR中是否有特殊的行为使这成为可能?这也可能解释为什么通用结构约束不允许可空类型。
最好的问候, Oliver Hanappi
3个回答

19
如果你这样做:
int? x = null;
if (x == null)

使用HasValue就可以了。

使用Object.ReferenceEquals将首先装箱该值 - 这将把空值转换为null引用(这确实是CLR的特殊行为)。当可空值类型装箱时,结果要么是null引用,要么是基础值类型的box。换句话说,不存在可空值类型的装箱值。


谢谢,特殊的装箱行为正是我一直在寻找的东西! - Oliver Hanappi

5

可空类型的比较并不总是返回true。 例如,考虑以下示例:

int? n = null;
int? m = 5;

Console.WriteLine(n == null);  // prints True
Console.WriteLine(m == null);  // prints False

CLR 对 Nullable 类型有特殊的装箱行为,使得引用比较按照你所期望的方式工作。实际上,该结构体的 Value 属性被装箱成一个 object


我怀疑 OP 问的是为什么在不同的测试方式中,它对空值返回 true,而对非空值则不返回。 - Jon Skeet
@Jon Skeet:是的,我也怀疑。但是这个问题可能暗示了一种实际情况并非如此的行为,这就是为什么我选择强调这一点的原因。 - LBushkin
1
事实上,我和LBushkin一样理解了那个问题,+1。 - nothrow
对不起我的问题不清楚,我实际上是在谈论可空类型表示没有值的情况。 - Oliver Hanappi
@Oliver Hanappi:不用担心,我并不是想要无礼,只是想指出问题的表述方式可能会导致一些误解。由于SO被许多用户用作知识库,指出这类问题对社区非常有帮助。 - LBushkin

2

是的,Nullable<T>是一种特殊的结构体,它得到了编译器的支持。我已经在这里写过一个关于它被编译成IL时发生了什么的博客 (链接)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接