空条件运算符和 !=

Posted

技术标签:

【中文标题】空条件运算符和 !=【英文标题】:Null-conditional operator and != 【发布时间】:2017-12-01 07:27:12 【问题描述】:

随着C#中Null-Conditional Operators的引入,用于后续评测,

if (instance != null && instance.Val != 0)

如果我这样重写,

if (instance?.Val != 0)  

如果实例是空引用,它将被评估为true;它的行为就像

if (instance == null || instance.Val != 0)

那么使用这种新语法重写评估的正确方法是什么?

编辑:

instance 是从 JSON 反序列化的大对象的字段。这样的代码有不少,首先检查该字段是否在JSON中,如果是,检查Val属性是否不等于常量,只有两个条件都为真,做一些操作。

可以重构代码本身以使逻辑流程更“有意义”,正如 Peter 在他的评论中所指出的那样,尽管在这个问题中,我对如何使用 null-conditional operators!= 感兴趣。

【问题讨论】:

我很想做if ((instance?.Val ?? 0) != 0)之类的事情 其实它的行为类似于instance?.Val != 0,因为短路的null不可能等于0,所以整个表达式是true。坦率地说,没有足够的上下文来了解解决表达式的“正确方法” 是什么。对我来说,null 值和零值都导致相同的代码执行块对我来说似乎很奇怪。鉴于您处于这种情况,可能有一些更好的方法来处理这种情况。或者也许,只是不要试图在这里硬塞空条件,因为它要做的就是使代码less可读。 我创建了一个fiddle 的问题。彼得,除非 Val 具有非零/非空值,否则它似乎可以防止执行操作,如果您正在创建类似 PATCH API 方法的东西,这对我来说似乎没有错。 @john,谢谢,我刚刚玩过那个 sn-p。在这种情况下,我会坚持使用旧的空值检查,因为代码变得不那么可读了,它超过了节省一些输入的好处。 【参考方案1】:

使用 Null-Conditional 运算符,返回值总是可以为 null

if ((instance?.Val ?? 0) != 0)

如果 instance 为 null,则 instance?.Val 也将为 null(在您的情况下可能是 int?)。因此,在与任何内容进行比较之前,您应该始终检查空值:

if ((instance?.Val ?? 0) != 0)

这意味着: 如果instance?.Val 为null(因为instance 为null)则返回0。否则返回instance.Val。接下来将该值与 0(不等于)进行比较。

【讨论】:

我花了 2 分钟寻找两个代码示例之间的差异【参考方案2】:

您可以使用空合并运算符:

instance?.Val ?? 0

instance 为空或instance 不为空但Val 为空时,上述表达式的计算结果为0。否则将返回Val 的值。

【讨论】:

【参考方案3】:
if ((instance?.Val).GetValueOrDefault() != 0)  

?条件运算符会自动将 .Val 属性视为 Nullable。

【讨论】:

是的,编译后(instance?.Val).GetValueOrDefault()(instance?.Val ?? 0)相同,其中0是编译时常量,也称为default(int)

以上是关于空条件运算符和 !=的主要内容,如果未能解决你的问题,请参考以下文章

如何在 WPF 中使用空条件运算符? [复制]

条件逻辑运算符成员运算与身份运算

? 的可空类型问题:条件运算符

不能无条件调用运算符“*”,因为接收者可以为“null”。尝试向目标添加空检查('!')

在处置模式中使用空条件运算符时 CA2213 触发

空条件运算符不适用于泛型方法中的 Func<T>