合并顺序检查

时间:2018-01-29 13:40:09

标签: c# .net resharper

有一个类A,其中包含Nullable属性Prop

public class A {
    int? Prop {get; set;} 
}

...

我有a类型的对象A 在条件:

if (a != null && a.Prop.HasValue) { // <--
   int res = a.Prop;
}

我收到了建议"Merge sequential checks"

我不明白我该怎么做。 a?.Prop.HasValue将无效

我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

Resharper转换原始逻辑:

if (a != null && a.Prop.HasValue)

进入这个:

if (a?.Prop != null)

因此,只要表达式不评估为null,该块就会执行,如果nulla,它将评估为null(感谢?.)或a.Propnull(正常情况下)。在这两个版本中,只要aa.Prop都有值“(或者真的”......没有值“),你基本上都会说”做这些事情。“

但是,我并不完全确定我喜欢这些重构。事实上,我可以看到in this other question JetBrains本身并不一定认为这些是好的重构,因为它们使代码更难理解。

事实上,我认为可能是因为这些形式难以理解,这种“合并顺序检查”重构在某些情况下实际上是已破坏,因为至少end of April 2017({{ 3}}),目前仍然是截至2018年2月底。

当你的表达式包含||运算符和AnyAll LINQ方法中的任何一个(以及其他情况,如函数调用返回)时,请注意使用重构一个bool)。

假设:

var array = new[] { 1, 2, 3, 4, 5 };

Resharper将转换为:

if (array == null || !array.Any())

进入这个:

if (!array?.Any() != true) // WRONG

如果arraynull,或者array为空,则原件显然是“执行此操作”。

但是第二个版本说的是什么?这很难读,你几乎无法判断它是对还是错。

!= true实际上意味着“如果表达式为nullfalse”则执行此操作。好的,所以如果array为空,我们会这样做,到目前为止这是好的。但是,如果数组不为空,那么呢?

好吧,如果数组为空,我们想要做的事情。如果数组为空,则array?.Any()将为false

然后我们有!false,即true

然后我们true != true false

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

因此,Resharper向后获得逻辑,如果 一个值,则执行该块,而不是一个值。

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