使用Null条件运算符检查可能为null的对象的值

Dan*_*ger 17 c# c#-6.0 null-conditional-operator

我一直在玩C#6的Null Conditional Operator(这里有更多信息).

我非常喜欢语法,我认为它使代码更具可读性,但我认为当你遇到一个本身可能为null的对象上的属性值时,代码究竟要做什么是值得怀疑的.

例如,如果我有一个带有十进制属性的类,并且我想要对该十进制值进行条件检查,我会写如下:

if (foo?.Bar > max)
{
   // do something
}
Run Code Online (Sandbox Code Playgroud)

从表面上看,这看起来很棒......如果foo不为null,则获取Bar的值并检查它是否大于最大值,如果是,则执行某些操作.

但是,如果foo为null会怎么样?!

这篇关于C#6的新功能和改进功能的文档说明了这些内容:

如果实际上对象的值为null,则null条件运算符将返回null.它将对Bar的调用短路,并立即返回null,避免编程错误,否则会导致NullReferenceException.

我在这里写了一个小提琴,表明它确实起作用,正在做我期待它做的事情但是我无法理解它是如何决定条件的结果.

短路如何等于假?在我的脑海中,这段代码现在要说"如果foo为null,检查null是否> max,这是不可能的,所以返回false"或"如果foo为null,那么foo!= null将返回false,所以你得到一个假"但文档说null条件检查返回null,而不是false.

mjw*_*lls 16

短路如何等于假?

if (foo?.Bar > max)
{
   // do something
}
Run Code Online (Sandbox Code Playgroud)

大致相当于到:

Decimal? bar = null;
if (foo != null)
    bar = foo.Bar;

if (bar > max)
{
   // do something
}
Run Code Online (Sandbox Code Playgroud)

因此,短路不相等false.它等于Decimal?(可空Decimal)然后与之比较max.

另请参见:比较运算符如何与null int一起使用?

  • 点击我的帖子@DannyLager中的链接.其中一个展示了罗斯林如何降低它.它基本上将`?.`转换成我上面的东西(不完全相同,但足够接近). (2认同)
  • `文档说它返回null`从根本上说,它需要返回特定**类型**的"null".鉴于`Bar`属性是`Decimal`,`Decimal?`是显而易见的选择. (2认同)

Fru*_*erg 7

它将对Bar的调用短路

表示.如果父项已经为空,则停止检查对象引用链中的以下步骤().这意味着比较运算符不会受到影响,因为您使用的是值而不是在链移动.此行为称为空传播.你可以在Code ProjectDave Fancher找到一些不错的描述.

使用null条件运算符返回可以为null的值double?.然后将该值与之进行比较max.微软很好地描述了这种比较中null的行为:

当您使用可空类型进行比较时,如果其中一个可空类型的值为null而另一个不是,则除了!=(不等于)之外,所有比较都会计算为false.

这意味着:

if (null > max)
{
    //never called
}
Run Code Online (Sandbox Code Playgroud)