【问题标题】:Null-propagation replacement for null check prior conditional statement空值检查先验条件语句的空值传播替换
【发布时间】:2017-04-20 00:07:18
【问题描述】:

看到一个similar question后,想知道是不是下面这个表达式……

if (attribute != null && attribute.Description == input)

... 与以下空传播变体的行为(几乎)相同?

if (attribute?.Description == input)

到目前为止,我只能确定以下(有些细微的)差异:

  • 如果input 是不可为空的类型,则不可能
  • 如果input 本身就是null,则行为将被改变

我错过了什么吗?还是有其他行为上的差异?


编辑:最后,我为第一个 sn-p 找到的唯一故障安全替代方案是:

if (attribute?.Description?.Equals(input) ?? false)

【问题讨论】:

  • attribute 在第二种情况下只被评估一次,所以你永远不会得到NullReferenceException。在第一种情况下,如果 attribute 在评估第一个条件之后但在评估第二个之前从非 null 更改为 null,您仍然会看到异常...
  • 如果您不想让input 成为null,您应该先检查一下。那么就没有区别了,因为可以将 nullable 与 non-nullable 进行比较。
  • @TimSchmelter 这实际上对您没有帮助。关键是当input 为空时,两个 sn-ps behave 不同,并且它们这样做的方式是,对于第二个 sn-p,您不能只检查它第一的;如果允许 input 为 null,则您需要将第二个 sn-p 重构为类似于第一个的东西,以便它返回正确的结果。
  • 在得到问题的答案后,您不应该更改问题的内容。
  • @Servy 好的,很抱歉。我想保留一个更新的列表,在哪里添加/删除差异。还认为如果他们不阅读答案,列表中的第一个错误陈述可能会误导其他人。感谢您的提示!

标签: c# null language-features c#-6.0 null-propagation-operator


【解决方案1】:

如果input 是不可为空的类型,代码将工作。所有不可为空的类型都隐式转换为可空的类型,因此input 将被简单地提升为可空的类型,以便与属性值进行比较。

正如您所提到的,行为上的唯一区别是,如果 input 是 null,那么第二个 sn-p 无法区分 attribute 是 null,什么时候应该是 @987654327 @,其中Description 是null,它应该是true。

哦,这是假设attribute 是一个局部变量或字段。如果它是一个属性(或者实际上是一个更复杂的表达式),那么它可能会产生副作用或在计算两次时产生不同的值,就像第一个 sn-p 而不是第二个一样,这是行为上的差异。

这当然是假设一个单线程上下文。在多线程上下文中,如果 attribute 可以从另一个线程访问(因为它是一个可访问的字段,或者因为它在暴露给另一个线程的 lambda 中被封闭),那么每次计算的值都可能不同,所以两个 sn-ps 不同的原因与上一段中描述的相同。

【讨论】:

  • 你怎么知道它从来没有null?处理合同?
  • 在我的例子中,输入来自预定义的配置文件。
猜你喜欢
  • 2017-11-21
  • 2022-09-27
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多