私が Java で遭遇した SonarLint ルールの大部分は、もっともらしく正当化されているように見えました。しかし、VB.NET 用の SonarLint を使い始めて以来、いくつかのルールに出くわし、それらの有用性や、それらが正しく機能しているかどうかさえ疑問に思うようになりました。
これが、いくつかの VB.NET コンストラクトを次善の方法で使用したことによる単純な問題なのか、それともルールに実際に欠陥があるのかを知りたいです。(この質問が少し長い場合は申し訳ありません。個々のルールごとに個別の質問を作成する必要があるかどうかわかりませんでした。)
私が見つけた次のルールは、実際には誤検知として現れるいくつかのケースを考慮しないままにしておくことがわかりました:
S1871 : 同じ条件構造内の 2 つの分岐がまったく同じ実装
であってはなりません。条件がチェックされる順序が実際に重要な場合があるため、これは多くの誤検知を引き起こすことがわかりました。次の疑似コードを例にとります。If conditionA() Then doSomething() ElseIf conditionB() AndAlso conditionC() Then doSomethingElse() ElseIf conditionD() OrElse conditionE() Then doYetAnotherThing() '... feel free to have even more cases in between here Else Then doSomething() 'Non-compliant End If
この Sonar ルールに従い、コードを同じように動作させたい場合は、各 ElseIf 条件の否定バージョンを最初の If 条件に追加する必要があります。
別の例は、次のスイッチです。Select Case i Case 0 To 40 value = 0 Case 41 To 60 value = 1 Case 61 To 80 value = 3 Case 81 To 100 value = 5 Case Else value = 0 'Non-compliant
スイッチで最後のケースを使用しても問題はありません。確かに、前もって 0 に初期化
value
して最後のケースを無視することもできましたが、そうすると、必要以上に代入操作が 1 つ増えてしまいます。default
そして、Java ルールセットは、すべてのスイッチに常に大文字と小文字を区別するように私を条件づけました。S1764 : 2 項演算子の両側で同じ式を使用しないでください
このルールは、一部の関数が呼び出すたびに異なる値を返す可能性があることを考慮していないようです。たとえば、要素にアクセスするとコレクションから要素が削除されるコレクションなどです。stack.Push(stack.Pop() / stack.Pop()) 'Non-compliant
ただし、これが特別な例外を設けるにはエッジケースが多すぎるかどうかは理解しています。
私が実際に確信していない次のルール:
- S3385 : "Exit" ステートメントは使用しないでください。の方が より読みやすい
ことに同意しまたはループから抜け出すためにシングルを使用するのは本当に悪いことJava の SonarLint ルールでは、問題としてフラグを立てる前に、ループ内で単一の使用を許可しています。その点で、VB.NET のデフォルトがより厳密である理由はありますか? それとも、ほぼすべてのループの問題を LINQ 拡張メソッドとラムダで解決できるという前提に基づいてルールが構築されているのでしょうか?Return
Exit Sub
Exit For
For
For Each
break;
- S2374 : 署名された型は、署名されていないものより優先される
べきです。私のコードでは、ID 値に UInteger のみを使用しています (私の場合、負の値は必要なく、Long はメモリの無駄になるため)。これらは List(Of UInteger) に格納され、他の UInteger とのみ比較されます。このルールは私の場合にも関係がありますか (比較はルールで言及されているこれらの「算術演算子」の一部ですか)、落とし穴は正確には何ですか? そうでない場合は、宣言ではなく、符号なしの型を含む算術演算にその規則を適用する方がよいのではないでしょうか? S2355 : 配列作成式の代わりに配列リテラルを使用する必要があります
VB.NET についてはよく知らないかもしれませんが、初期化長が実行時にのみ知られていますか? これは偽陽性ですか?Dim myObjects As Object() = New Object(someOtherList.Count - 3) {} 'Non-compliant
確かに、おそらく List(Of Object) を使用できます。でもとにかく気になる。