ReSharper`MergeSequentialChecks`和'MergeSequentialChecksWhenPossible`之间有什么区别?

gor*_*nin 7 c# resharper c#-6.0

我想弄清楚这两条规则之间有什么区别?

  • MergeSequentialChecks
  • MergeSequentialChecksWhenPossible

文档没有说明第二个. https://www.jetbrains.com/help/resharper/2016.1/MergeSequentialChecks.html

这对我来说不清楚这是什么意思WhenPossible

如果ReSharper建议应用第一个规则并合并我的顺序检查,那么确实可能.怎么可能不可能?

这是一个要检查的代码示例.

public class Person
{
    public string Name { get; set; }
    public IList<Person> Descendants { get; set; }
}

public static class TestReSharper
{
    // Here `MergeSequentialChecks` rule is triggered for both `&&` operands.
    public static bool MergeSequentialChecks(Person person)
    {
        return person != null && person.Descendants != null && person.Descendants.FirstOrDefault() != null;
    }

    // Here `MergeSequentialChecksWhenPossible` rule is triggered.
    public static bool MergeSequentialChecksWhenPossible1(Person person)
    {
        return person != null && person.Descendants.Any();
    }

    // Here `MergeSequentialChecksWhenPossible` rule is triggered.
    public static bool MergeSequentialChecksWhenPossible2(Person person)
    {
        return person.Descendants != null && person.Descendants.Any();
    }
}
Run Code Online (Sandbox Code Playgroud)

con*_*low 7

使用"(如果可能)"标签进行代码检查背后的想法很简单:我们决定不使用默认的R#设置建议可能的代码转换,因为生成的代码可能导致可读性降低或变得难以理解.这个关于建议与否的决定是通过特设启发式方法完成的.

当我们第一次实现C#6.0相关的代码建议和转换并在我们可用的大解决方案中查看它们的结果时,我们认为近似约2/3的检查发生,如"合并顺序检查"/"使用空传播"不应该建议做代码转换.例如,我们认为在这样的代码的情况下:

if (node != null && node.IsValid()) { ... }
Run Code Online (Sandbox Code Playgroud)

...使用?.运算符并引入"提升" operator==(bool, bool)运算符而非bool?类型值没有实际好处:

if (node?.IsValid() == true) { ... }
Run Code Online (Sandbox Code Playgroud)

加上不同的开发者对如何检查类型的值不同意见bool?的存在true(有些人喜欢有?? false相反,但会使生成的代码even?.more ?? questionable).

因此,在上面的顺序检查合并的情况下肯定是"可能的",但我们不建议使用默认的R#设置(正确的默认设置是一项巨大的责任),让用户能够查看所有案例通过启用"(如果可能)" - 相同代码检查的版本.到目前为止,我可以看到,目前我们只检查在"合并顺序检查"检查中不生成提升的布尔检查,其他检查有更多的启发式,例如:

if (stringBuilder != null) { // "Use null propagation"
  stringBuilder.Append("hello");
}
Run Code Online (Sandbox Code Playgroud)

上面的代码值得建议使用条件调用操作符:

stringBuilder?.Append("hello");
Run Code Online (Sandbox Code Playgroud)

虽然按顺序使用条件调用两次或更多次是值得怀疑的......

if (stringBuilder != null) { // no suggestion
  stringBuilder.Append("hello");
  stringBuilder.Append("world");
  stringBuilder.Append("!!!");
}
Run Code Online (Sandbox Code Playgroud)

ps上下文操作"合并顺序检查"/"到空传播" 始终在可以进行转换时启用,尽管代码检查状态及其严重性.