合并顺序检查

DDa*_*Dan 1 .net c# resharper

有一个A具有 Nullable 属性的类Prop

public class A {
    int? Prop {get; set;} 
}
Run Code Online (Sandbox Code Playgroud)

...

我 有条件a类型的对象A

if (a != null && a.Prop.HasValue) { // <--
   int res = a.Prop;
}
Run Code Online (Sandbox Code Playgroud)

我收到建议 "Merge sequential checks"

我不明白我怎么能那样做。a?.Prop.HasValue不管用

我在这里缺少什么?

Dav*_*eau 7

Resharper 转换您的原始逻辑:

if (a != null && a.Prop.HasValue)
Run Code Online (Sandbox Code Playgroud)

进入这个:

if (a?.Prop != null)
Run Code Online (Sandbox Code Playgroud)

因此,只要表达式不计算为null,块就会执行,并且null如果anull(感谢?.)或如果a.Propnull(正常情况下),它将计算为。在这两个版本,你基本上是说:“做这个东西,只要双方aa.Prop具有价值”(或真“......不不具有值”)。

不过,我并不完全确定我喜欢这些重构。事实上,我可以在另一个问题中看到 JetBrains 自己并不一定认为这些是好的重构,因为它们使代码更难理解。

事实上,我认为可能是因为这些形式更难理解,这种“合并顺序检查”重构实际上在某些情况下被破坏了,至少从 2017 年 4 月末也在这里)开始,目前仍然是 2018 年 2 月末.

当您的表达式既包含||运算符又包含AnyAllLINQ 方法(以及其他情况,例如返回 a 的函数调用bool)时,请注意使用重构。

鉴于:

var array = new[] { 1, 2, 3, 4, 5 };
Run Code Online (Sandbox Code Playgroud)

Resharper 将转换为:

if (array == null || !array.Any())
Run Code Online (Sandbox Code Playgroud)

进入这个:

if (!array?.Any() != true) // WRONG
Run Code Online (Sandbox Code Playgroud)

原文显然是“如果arraynull,或者如果array是空的,就做这件事”。

但是第二个版本说什么?读起来太难了,你几乎无法判断它是对还是错。

!= true有效地表示“如果表达式是nullfalse”,则执行此操作。好的,所以如果array为空,我们会这样做,到目前为止还不错。但是,如果 array不是 null,那么呢?

好吧,我们想在数组为空时做这些事情。如果数组为空,那么array?.Any()将是false

然后我们有!false,就是true

然后我们有true != true哪个是false

所以我们有“如果数组为空......不要执行块”,这与我们想要的相反。

所以ReSharper的已经得到了逻辑倒退,如果有块将执行一个值,而不是如果没有一个值。

即使没有这个缺陷,代码也很难阅读,所以我觉得通常应该避免这种重构。