合并顺序检查
Merge Sequential Check
有一个 class A
with 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
不会工作
我在这里错过了什么?
Resharper 转换您的原始逻辑:
if (a != null && a.Prop.HasValue)
进入这个:
if (a?.Prop != null)
因此,只要表达式的计算结果不为 null
,该块就会执行,如果 a
为 null
,它将计算为 null
(感谢 ?.
) 或者如果 a.Prop
是 null
(正常)。在这两个版本中,您基本上都是在说 "do this stuff as long as both a
and a.Prop
have values"(或者实际上是“...没有值”)。
不过,我不确定我是否喜欢这些重构。事实上,我可以看到 JetBrains 自己并不一定认为这些是好的重构,因为它们使代码更难理解。
事实上,我认为可能具体是因为这些形式更难理解,这个 "Merge Sequential Checks" 重构在某些情况下实际上 broken,因为至少 end of April 2017 (also here),目前仍截至 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
原文明显"do this stuff if array
is null
, or if array
is empty".
但是第二个版本说了什么?很难读懂,你几乎不知道它是对还是错。
!= true
实际上意味着 "do this if the expression was null
or false
"。好的,如果 array
为 null,我们将执行此操作,到目前为止这很好。但是,如果数组 不是 null,那么呢?
好吧,我们想在数组为空时执行这些操作。如果数组为空,则 array?.Any()
将是 false
.
然后我们有!false
,也就是true
。
然后我们有 true != true
即 false
。
所以我们有 "if the array is empty ... don't execute the block",这与我们想要的相反。
所以 Resharper 的逻辑是倒过来的,如果 是 值,而不是 不是 时,块将执行一个值。
即使没有这个缺陷,代码也很难阅读,所以我觉得通常应该避免这种重构。
有一个 class A
with 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
不会工作
我在这里错过了什么?
Resharper 转换您的原始逻辑:
if (a != null && a.Prop.HasValue)
进入这个:
if (a?.Prop != null)
因此,只要表达式的计算结果不为 null
,该块就会执行,如果 a
为 null
,它将计算为 null
(感谢 ?.
) 或者如果 a.Prop
是 null
(正常)。在这两个版本中,您基本上都是在说 "do this stuff as long as both a
and a.Prop
have values"(或者实际上是“...没有值”)。
不过,我不确定我是否喜欢这些重构。事实上,我可以看到
事实上,我认为可能具体是因为这些形式更难理解,这个 "Merge Sequential Checks" 重构在某些情况下实际上 broken,因为至少 end of April 2017 (also here),目前仍截至 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
原文明显"do this stuff if array
is null
, or if array
is empty".
但是第二个版本说了什么?很难读懂,你几乎不知道它是对还是错。
!= true
实际上意味着 "do this if the expression was null
or false
"。好的,如果 array
为 null,我们将执行此操作,到目前为止这很好。但是,如果数组 不是 null,那么呢?
好吧,我们想在数组为空时执行这些操作。如果数组为空,则 array?.Any()
将是 false
.
然后我们有!false
,也就是true
。
然后我们有 true != true
即 false
。
所以我们有 "if the array is empty ... don't execute the block",这与我们想要的相反。
所以 Resharper 的逻辑是倒过来的,如果 是 值,而不是 不是 时,块将执行一个值。
即使没有这个缺陷,代码也很难阅读,所以我觉得通常应该避免这种重构。