有一个类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
将无效
我在这里缺少什么?
答案 0 :(得分:2)
Resharper转换原始逻辑:
if (a != null && a.Prop.HasValue)
进入这个:
if (a?.Prop != null)
因此,只要表达式不评估为null
,该块就会执行,如果null
为a
,它将评估为null
(感谢?.
)或a.Prop
是null
(正常情况下)。在这两个版本中,只要a
和a.Prop
都有值“(或者真的”......没有值“),你基本上都会说”做这些事情。“
事实上,我认为可能是因为这些形式难以理解,这种“合并顺序检查”重构在某些情况下实际上是已破坏,因为至少end of April 2017({{ 3}}),目前仍然是截至2018年2月底。
当你的表达式包含||
运算符和Any
或All
LINQ方法中的任何一个(以及其他情况,如函数调用返回)时,请注意使用重构一个bool
)。
假设:
var array = new[] { 1, 2, 3, 4, 5 };
Resharper将转换为:
if (array == null || !array.Any())
进入这个:
if (!array?.Any() != true) // WRONG
如果array
为null
,或者array
为空,则原件显然是“执行此操作”。
但是第二个版本说的是什么?这很难读,你几乎无法判断它是对还是错。
!= true
实际上意味着“如果表达式为null
或false
”则执行此操作。好的,所以如果array
为空,我们会这样做,到目前为止这是好的。但是,如果数组不为空,那么呢?
好吧,如果数组为空,我们想要做的事情。如果数组为空,则array?.Any()
将为false
。
然后我们有!false
,即true
。
然后我们true != true
false
。
所以我们“如果数组是空的...... 不执行块”,这与我们想要的相反。
因此,Resharper向后获得逻辑,如果 一个值,则执行该块,而不是不一个值。
即使没有这个缺陷,代码也很难阅读,所以我觉得通常应该避免这种重构。