我在 Java 中遇到的绝大多数 SonarLint 规则似乎都是合理且合理的。然而,自从我开始为 VB.NET 使用 SonarLint 以来,我遇到了一些规则,这些规则让我质疑它们的用处,甚至质疑它们是否正常工作。
我想知道这是否只是我以次优方式使用某些 VB.NET 构造的问题,或者该规则是否真的有缺陷。(抱歉,如果这个问题有点长。我不知道是否应该为每个单独的规则创建一个单独的问题。)
我发现以下规则忽略了一些实际上会出现误报的情况:
S1871:同一个条件结构中的两个分支不应该有完全相同的实现
我发现这个分支给我带来了很多误报,因为有时检查条件的顺序实际上很重要。以下面的伪代码为例: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
在 switch 中使用最后一个 case 应该没有什么问题。没错,我本可以
value
事先初始化为 0 并忽略最后一种情况,但随后我会进行一次不必要的赋值操作。Java 规则集使我总是default
在每个开关中放置一个案例。S1764 : 相同的表达式不应该用在二元运算符的两边
这个规则似乎没有考虑到某些函数每次调用它们时可能返回不同的值,例如在访问元素的集合中将其从集合中删除:stack.Push(stack.Pop() / stack.Pop()) 'Non-compliant
不过,我理解这是否过于极端,无法为其做出特殊例外。
以下规则我实际上不确定:
- S3385:不应该使用“退出”语句
虽然我同意它Return
比 更具可读性Exit Sub
,但使用单个Exit For
来打破 aFor
或For Each
循环真的很糟糕吗?break;
Java 的 SonarLint 规则允许在将其标记为问题之前在循环中使用单个VB.NET 中的默认设置在这方面更加严格,这是有原因的吗?或者该规则是否建立在您可以使用 LINQ 扩展方法和 lambda 解决几乎所有循环问题的假设之上? - S2374 : 有符号类型应优先于无
符号类型 该规则基本上规定不应使用无符号类型,因为它们“具有与有符号类型不同的算术运算符 - 很少有开发人员理解的运算符”。在我的代码中,我只将 UInteger 用于 ID 值(因为我不需要负值,而且 Long 在我的情况下会浪费内存)。它们存储在 List(Of UInteger) 中,并且仅与其他 UInteger 进行比较。这条规则是否与我的案例相关(比较是规则提到的这些“算术运算符”的一部分),究竟会有什么陷阱?如果不是,那么将该规则应用于涉及无符号类型的算术运算而不是它们的声明不是更好吗? S2355:应该使用数组文字而不是数组创建表达式
也许我不太了解 VB.NET,但是在以下我想创建一个固定大小的数组的情况下,我将如何满足这个规则,其中初始化长度只在运行时知道?这是假阳性吗?Dim myObjects As Object() = New Object(someOtherList.Count - 3) {} 'Non-compliant
当然,我可能只使用 List(Of Object)。但无论如何我很好奇。