Null-conditional运算符和!=

21

引入了 C# 的 Null-Conditional 运算符 后,对于以下表达式的求值:

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

如果我这样重写它,

if (instance?.Val != 0)  

如果实例是一个 null 引用,则它将评估为true; 它的行为类似于

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

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

编辑:

instance 是从JSON反序列化的一个大对象的字段。有许多类似这样的代码,首先检查字段是否在JSON中,如果是,则检查Val属性是否不等于常量,只有两个条件都为真时,才执行某些操作。

代码本身可以重构以使逻辑流更加“合理”,正如Peter在他的评论中所示,但在这个问题中,我想知道如何使用null-conditional operators!=


2
我会倾向于这样做:if ((instance?.Val ?? 0) != 0) - ProgrammingLlama
2
实际上,它的行为类似于 instance?.Val != 0,由于短路的 null 不可能等于 0,整个表达式是 true。坦白地说,没有足够的上下文来知道如何正确处理表达式。对我来说,一个 null 值和一个零值都导致相同的代码执行块似乎很奇怪。考虑到你处于这种情况,可能有更好的方法来处理这种情况。或者,也许不要试图在这里强行使用 null-conditional,因为它只会使代码变得更加难以阅读。 - Peter Duniho
1
我创建了一个问题的 fiddle。Peter,这似乎是一种保护措施,防止执行操作,除非Val具有非零/非空值,如果您要创建类似于PATCH API方法的东西,这对我来说似乎是没有错的。 - ProgrammingLlama
2
@john,谢谢,我刚刚试用了那个代码片段。在这种情况下,我会坚持使用旧的空值检查,因为代码变得不太易读,这超过了节省一些打字的好处。 - kennyzx
3个回答

13

使用 Null-Conditional 运算符,返回值始终可以为 null。

if ((instance?.Val ?? 0) != 0)
如果实例是 null,那么 instance?.Val 也将为 null(在你的情况下可能是 int?)。因此,在与任何内容进行比较之前,您应始终检查是否为null:
if ((instance?.Val ?? 0) != 0)
这意味着: 如果 instance?.Val 为 null(因为 instance 为 null),则返回 0。否则返回 instance.Val。接下来将此值与 0 进行比较(不相等)。

1
我花了2分钟查找两个代码示例之间的差异。 - Artfaith

11
您可以使用null coallescing运算符:
instance?.Val ?? 0

instance为null或者instance不为null但是Val为null时,上述表达式将会计算为0。否则将返回Val的值。


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

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


是的,(instance?.Val).GetValueOrDefault()在编译后将与(instance?.Val ?? 0)相同,其中0是编译时常量,也称为default(int) - Jeppe Stig Nielsen

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