更改此条件,使其不总是评估为“真”
Posted
技术标签:
【中文标题】更改此条件,使其不总是评估为“真”【英文标题】:Change this condition so that it does not always evaluate to 'true' 【发布时间】:2018-02-10 07:30:38 【问题描述】:SonarQube 为什么抱怨这部分代码?
我检查了这段代码,但这个值并不总是正确的。
public static void WriteJson(object value)
decimal decimalValue = ((decimal?)value).Value;
int intValue = (int)decimalValue;
if (decimalValue == intValue)
Console.WriteLine(intValue);
else
Console.WriteLine(decimalValue);
Console.ReadKey();
SonarQube 为什么抱怨这个?
【问题讨论】:
除非 SonarQube 有一根魔杖知道你将在运行时传入什么,否则这是错误的。而且我不喜欢欺骗你的工具,尤其是当它们建议重构会破坏代码时。 疯狂猜测:SonarQube 看到decimalValue 转换为int 并返回到decimal,因此它假设(错误地)该值((decimal)intValue
)是原始的decimalValue - 这意味着条件是总是正确的。如果它是演员而不是转换,那将是正确的。
【参考方案1】:
误报与我们的数据流分析引擎中的缺陷有关 - 它没有考虑浮点数和整数之间的转换(目前),并且无法识别浮点数何时被截断。
我将尝试详细说明一下:数据流分析引擎会跟踪分析方法中的局部变量的值,当为变量分配新值时,引擎会创建一个表示实际值的特殊对象.当您将一个变量分配给另一个变量时,该对象保持不变。例如:
var x = 5; // the symbol of x is associated with value_0
var y = x; // the symbol of y is associated with value_0
if (x == y) // value_0 is compared with value_0 --> always true
我们分配的值不包含类型信息(还),我们无法检测到(还)像您这样的情况的变化:
var x = 5.5; // the symbol of x is associated with value_0
var y = (int)x; // the symbol of y is associated with value_0 (wrong)
if (x == y) // false positive
我们会生成误报,但它们相对较少,因为大多数类型转换不会生成新值。
感谢您的反馈,我们将调查in the near future。
【讨论】:
【参考方案2】:看起来 SonarQube 检测到您正在为两个变量分配相同的值,假设传递给方法的值等于 2
1. decimal decimalValue = 2
2. int intValue = (int)decimalValue;
因此decimalValue = 2
和intValue = 2
C# 编译器显然会将其转换为int
,因此如果您通过2.5
,if
比较将不会始终评估为true
。但很可能 SonarQube 只是不知道演员阵容。所以它假定总是正确的。
【讨论】:
【参考方案3】:我不是 SonarQube 的专家,但我猜这是因为 SonarQube 检测到您将 intValue
设置为 decimalValue
的舍入形式。然后你又将decimalValue
与intValue
的十进制形式进行比较。因此,在许多情况下,它会返回“true”。
要查看结果如何,假设 decimalValue 为“123.0”。然后,intValue 将恰好是“123”。然后,我们用“if”语句比较“123.0”(decimalValue的值)和“123.0”(intValue转换为十进制后的值),返回true。这将适用于所有整数。
【讨论】:
另一方面,如果value
为123.4,则条件为假以上是关于更改此条件,使其不总是评估为“真”的主要内容,如果未能解决你的问题,请参考以下文章