繁体   English   中英

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

[英]Using the Null Conditional Operator to check values on objects which might be null

我一直在玩C#6的Null条件运算符( 此处有更多信息 )。

我真的很喜欢这种语法,并且我认为它使代码更具可读性,但是当您遇到检查本身可能为null的对象的属性值时,对于代码将要执行的操作却存有疑问。

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

if (foo?.Bar > max)
{
   // do something
}

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

但是,如果foo为空怎么办?

有关C#6的新增功能和改进功能的本文档对这些方面的说明如下:

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

我在这里写了一个小提琴,表明它确实可以工作,并且正在执行我期望的操作,但是我无法理解它如何决定条件的结果。

短路如何等于假 在我的脑海中,这段代码现在将说“如果foo为null,请检查null是否大于max,这是不可能的,所以返回false”或“如果foo为null,那么foo!= null将返回false,因此您得到“ false”,但是文档说null条件检查返回的是null,而不是false。

短路如何等于假?

if (foo?.Bar > max)
{
   // do something
}

大致相当于

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

if (bar > max)
{
   // do something
}

因此,短路不等于false 等于Decimal? (可空的Decimal ), 然后将其与max 进行比较。

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

它将呼叫Bar短路

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

使用null条件运算符会返回可为null的值,例如double? 然后将该值与max进行比较。 Microsoft对这种比较中的null行为进行了很好的描述:

当您对可为空的类型执行比较时,如果其中一个可为空的类型的值是null而另一个不是,则所有比较的结果都为false,除了!=(不相等)。

这意味着:

if (null > max)
{
    //never called
}

Null Conditional Operator仅应用于与对象属性的多个分配有关的场景(请参阅对象映射等),在这种情况下,如果属性的空条件发生,它可能会很无聊。

或者也适用于以下情况:

int? count = customers?[0]?.Orders?.Count();  // null if customers, the first customer, or Orders is null 

if测试表达式中使用此运算符可能会导致意外行为,例如, 在fiddler上if语句案例中,您获得了“通过”测试(最后一个if语句),但其null ,这显然不是有效案例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM