CS.RESOURCE.UNBOXING
循环内的拆箱
每当因拆箱而从循环体内的对象提取值时,此检查器都会报告缺陷。将对象显式转换为基元类型时,编译器会自动应用拆箱。这是一项要占用大量计算资源的运算,所需的时间可能会比简单的基元类型分配多出几倍。当转换在循环内发生时,造成的性能影响尤为重大。Klocwork 会检测循环体内的自动拆箱并针对其潜在的性能影响发出警告。
漏洞与风险
拆箱可能会导致软件的响应能力下降,并且可能引起软件的总体性能降低。
缓解与预防
为防止这些负面影响,应避免自动拆箱。
漏洞代码示例
复制
using System;
namespace AutoUnBox
{
class UnBox {
public void Example1() {
TestUnBox test = new TestUnBox();
int count = 0;
for (long i = 0; i < 10; i++) {
count = (int)test + count; // CS.RESOURCE.UNBOXING
}
}
}
class TestUnBox {
TestUnBox() {}
private int value1 { set; get; }
public static explicit operator int(TestUnBox v) {
return value1;
}
}
}
Klocwork 针对第 8 行生成问题报告,这表示“自动拆箱在第 10 行应用于显式转换为基元类型 int 的 test”。在此情况下,自动拆箱在循环内进行,首先将常量整数值转换为对象,然后通过对象变量 count 进行 + 运算。
修正代码示例
复制
using System;
namespace AutoUnBox
{
class UnBox {
public void Example1() {
TestAutoBox countObj = new TestAutoBox();
TestAutoBox test = new TestAutoBox();
int countValue = 0;
for (long i = 0; i < 10; i++) {
countObj = test + countObj; // no CS.RESOURCE.AUTOBOXING
}
countValue = (int) testObj;
}
}
class TestUnBox {
TestUnBox() {
this.value1 = 0;
}
TestUnBox(int intValue) {
this.value1 = intValue;
}
private int value1 { set; get; }
public static implicit operator TestAutoBox(int v) {
return new TestAutoBox(v);
}
}
}
在经修正的代码中,第 11 行的两个操作数均为循环中的内置整数,因此未报告该问题。