2016-10-19 9 views
6

私はこれらの2つのルールの違いを理解しようとしていますか?ReSharper `MergeSequentialChecks`と` MergeSequentialChecksWhenPossible`の違いは何ですか?

  • MergeSequentialChecks
  • MergeSequentialChecksWhenPossible

ドキュメントは、第1については何も言いません。 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(); 
    } 
} 
+0

"Merge Sequential Checks"リファクタリングは多くの場合、式のロジックを逆にして壊れていることに注意してください。 –

答えて

6

「(可能性)」とのコード検査の背後にある考え方は、ラベルは簡単です:私たちは、デフォルトのR番号の設定で可能なコード変換を示唆しないことを決定し生成されたコードは減少し、読みやすさにつながる可能性があるためか、に困難になりましたわかる。示唆するかどうかのこの決定は、アドホックヒューリスティックを介して行われます。

最初にC#6.0関連のコードの提案と変換を実装し、その結果を私たちにとって利用可能な大きなソリューションでレビューしたところ、「順次チェックをマージする」「ヌル伝播を使用する」などの検査がほぼ2 /コード変換を行うべきではありません。たとえば、私たちは考えている。このようなコードの場合:

if (node != null && node.IsValid()) { ... } 

... bool?型の値を超えるoperator==(bool, bool)演算子「持ち上げる」?.オペレータとの導入を使用することの本当のメリットはありません

if (node?.IsValid() == true) { ... } 

プラス異なる開発者は、(一部ではなく?? falseを持っていることを好むが、それは結果のコードeven?.more ?? questionableになるだろう)trueであることのためのタイプbool?の値を確認する方法について異なる見解を持っています。

したがって、順次チェックのマージの場合は確かに "可能"ですが、デフォルトのR#設定(適切なデフォルト設定は大きな責任を負う)で推奨するつもりはありません。同じコード検査の "(可能な場合)"バージョンを有効にすることによってすべてのケースを表示することができます。私の知る限り見ることができ、現在、我々は唯一の「シーケンシャルチェックをマージ」検査で持ち上げたブールチェックを生成していないかどうかを確認、他の検査は、例えば、より多くのヒューリスティックを持っている:

if (stringBuilder != null) { // "Use null propagation" 
    stringBuilder.Append("hello"); 
} 

コードの条件付き呼び出し演算子を使用することを示唆価値が上:

stringBuilder?.Append("hello"); 

順次2回以上の条件付き呼び出しを使用している間は

if (stringBuilder != null) { // no suggestion 
    stringBuilder.Append("hello"); 
    stringBuilder.Append("world"); 
    stringBuilder.Append("!!!"); 
} 

PS ...疑問ですコード検査の状態とその重大度にかかわらず、変換が可能な場合、コンテキストアクション "順次検査のマージ"/"ヌル伝播"はです。は常に有効です。

+0

p.p.s.厳密に言えば、(可能な場合)検査の存在は、IntelliJ IDEAファミリのIDEのように、検査ごとの設定がないために発生します。私たちは、今後のR#版で検査ごとの設定を追加し、検査のバージョンとそれに対応する通常の検査をマージすることを検討しています。 – ControlFlow