我认为这是一个特别有趣的问题。我对此的看法与任何答案都不完全相同,所以请忍受我这么晚才来。
首先要注意的是,null
在 .NET 中与在其他一些上下文中并不完全相同null
,尽管它可以用来对它们进行建模。
例如在 SQL 中,我们可能有1 = null
and1 <> null
都 return null
,因为它的概念null
更接近数学,其中 null 不等于任何东西,包括 null,但也不完全不等于任何东西。
如果需要,我们可以为此使用 C# null
,但这并不是null
.NET 中默认含义的工作方式。
对于任何引用类型,null 具有特定定义的含义,并且可能具有上下文提供的其他含义。
具体含义是“没有这个类型的对象的实例”。
给定上下文中的其他含义可能是“整数值实际上是空的,而不是匹配任何整数”,或者“没有这样的项目集合,甚至不是空的”,或者“这是第一个这样的项目,所以没有更早的”等等,这取决于我们如何使用它。(此外,它可能意味着“哦,亲爱的,那真的不应该为空,最好抛出异常”)。
现在,我们可能想要大量使用这些额外的含义,以至于我们定义了一个对象等于 null 或至少不等于 null 有意义的情况。但是,我们有以下限制:
引用类型的值的 null 意味着没有该引用类型的实例的具体定义不会消失。
对于给定的 x 和 y,x == y
总是给出相反结果的语义不会消失。x != y
所以:
如果我们想要一个实例可以等于 null 的类型,它必须是值类型。
我们仍然必须x != null
返回对面x == null
。
现在,自从 .NET 2.0 以来,我们已经有了一个可以做到这一点的内置函数:(Nullable<T>
或T?
在 C# 语法中)。它还有一些额外的支持来帮助它在面对拳击时表现良好(这使得它在人的方式上表现得像一个引用类型,所以如果没有这些额外的支持,我们就会遇到复杂的情况,即x == null
返回 true 但(object)x == null
会返回 false。
情况也是如此,它Nullable<T>
可以处理几乎任何我们想对 null 使用这种稍微不同的语义的情况,这意味着如果我们可能想要定义的话,真的没有任何情况了Equals()
传递 null 时返回 true的方法。