可空类型如何处理null值与比较运算符?

26

有没有人对C#如何处理带有Nullable<T>类型的比较当比较的一方为null时有具体的信息呢?

据我通过编译器实验所了解,似乎比较总是返回false,但我找不到任何支持这一点的文档。这是语言的一个真正特性(因此我可以依靠它),还是实现细节可能会在未来版本中更改的问题?

换句话说,以下方法返回true是否意味着y.HasValue,你能否指向一些证明它确实如此的文档?

    public bool foo(int x, int? y)
    {
        return x < y;
    }

1
你为什么认为 null 会与任何值相等呢? - Andrew Barber
5个回答

51
有人对C#在一方为空时如何处理Nullable类型进行比较有具体的信息吗?
是的 - C#语言规范中7.3.7节有关系运算符的说明,此时是一种关系运算符:
对于关系运算符 < > <= >= ,如果操作数类型都是非nullable类型且结果类型为bool,则存在其提升形式。提升形式是通过向每个操作数类型添加一个单独的?修改器来构造的。如果一个或两个操作数为空,则提升后的操作符产生值false。否则,提升后的运算符展开操作数并应用基础运算符以产生bool结果。
其他运算符也有类似详细的部分。
当对语言某些方面的工作方式(以及它是保证还是实现特定)感到不确定时,应首先查阅C#语言规范。

3
下载规格说明书请访问:http://www.microsoft.com/download/en/details.aspx?id=7029。 - Anthony Pegram
规范的第4.1.10节的这部分也帮助我理解了这一点:“可以从T隐式地转换为T?。” - andrej351
Jon,这可能是一个冒险的问题,但你知道为什么<=>=运算符,“如果一个或两个操作数为null,则提升的运算符生成false值”吗?对我来说,这似乎很奇怪,因为(null == null) == true,但是(null <= null) == false - Rufus L

7
如果其中一个值为null,则比较结果将为false(!=除外)
当您使用可空类型进行比较时,如果一个可空类型的值为null而另一个不是,则所有比较都将评估为false,除了!=(不等于)。重要的是不要假设因为一个特定的比较返回false,相反的情况返回true。在以下示例中,10既不大于、也不小于null,也不等于null。只有num1 != num2评估为true。
来源:MSDN 链接

我不知道结果是否不同。然而,那个引用是在处理比较两个可空类型。 - Joe

2
MSDN在此问题上有如下说明:
当您使用可空类型进行比较时,如果其中一个可空类型的值为null而另一个不是,则除了!=(不等于)之外,所有比较都将评估为false。

http://msdn.microsoft.com/en-us/library/2cf62fcy(v=vs.100).aspx

这里是提供的代码示例:
int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
{
    Console.WriteLine("num1 is greater than or equal to num2");
}
else
{
    // This clause is selected, but num1 is not less than num2.
    Console.WriteLine("num1 >= num2 returned false (but num1 < num2 also is false)");
}

if (num1 < num2)
{
    Console.WriteLine("num1 is less than num2");
}
else
{
    // The else clause is selected again, but num1 is not greater than
    // or equal to num2.
    Console.WriteLine("num1 < num2 returned false (but num1 >= num2 also is false)");
}
if (num1 != num2)
{
    // This comparison is true, num1 and num2 are not equal.
    Console.WriteLine("Finally, num1 != num2 returns true!");
}
// Change the value of num1, so that both num1 and num2 are null.
num1 = null;
if (num1 == num2)
{
    // The equality comparison returns true when both operands are null.
    Console.WriteLine("num1 == num2 returns true when the value of each is null");
}

0
如果没有实现特定的CompareTo方法,那么我的研究告诉我对象将使用CompareTo(object)方法。对于int类型,您可以将其与int或对象进行比较。在这种情况下,它只检查对象是否为空。这是一个链接到int CompareTo(object)方法的链接,它详细说明了比较int和对象结果的原因。

http://msdn.microsoft.com/en-us/library/system.int32.aspx

我找不到确切的信息,但我没有看到任何迹象表明.NET框架已扩展以包括System.Nullable<T>每个<T>的CompareTo方法。

如果这是我的代码,我会保护自己并扩展Int类以包括CompareTo方法。


0

我知道我来晚了,但我也想发表一下我的看法。

如果我没记错的话,比较器的规则如下:

  • 如果 x 和 y 都为 null,则返回 0(它们相等)。
  • 如果 x 为 null,而 y 不为 null,则返回 -1(x 小于 y)。
  • 如果 x 不为 null,而 y 为 null,则返回 1(x 大于 y)。

对于所有非 null 值:

  • 当 x 的值小于 y 时,返回 -1。
  • 当 x 的值等于 y 时,返回 0。
  • 当 x 的值大于 y 时,返回 1。

就所有目的而言,当 Nullable<T> 没有值时,它被视为 null。因此,规则基本上是相同的。至少,这就是我编写比较器的方式。如果我做错了,那么天哪,我做错了,我真希望有人告诉我该如何修复它!


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