CS.RESOURCE.AUTOBOXING

循环内的自动装箱

每当循环体内发生因自动装箱而将值类型自动转换为引用类型对象时,此检查器会报告此类转换的任何实例。自动装箱由编译器应用于分配中,或者应用于值类型常量或变量与引用类型对象之间的二进制运算的应用程序中。自动装箱涉及分配堆上内存和构造对象,因此可能会消耗大量系统资源。当此类转换在循环内发生时,这种情况的影响尤为重大。

漏洞与风险

自动装箱会引起软件性能降低,从而影响所消耗的资源数量,并且可能导致软件响应能力下降或者可用资源完全耗尽。

缓解与预防

为防止这些负面影响,应避免自动装箱。

漏洞代码示例 1

复制
  using System;
  namespace AutoUnBox
  {
    class AutoBox {
      public void Example1() {
              TestAutoBox count = new TestAutoBox();
        for (long i = 0; i < 10; i++) {
          count += 0x2A;                       // CS.RESOURCE.AUTOBOXING
        }
     }
   }
   class TestAutoBox {
 
     TestAutoBox(int intValue) {
       this.value1 = intValue;
     }
 
     private int value1 { set; get; }
 
     public static implicit operator TestAutoBox(int v) {
       return new TestAutoBox(v);
    }
   }
 }

Klocwork 针对第 8 行生成问题报告,这表示“自动装箱在第 8 行应用于会自动转换为 count 的基元类型 int”。在此情况下,自动装箱在循环内进行,首先将常量整数值转换为对象,然后通过对象变量 count 进行 + 运算。

修正代码示例 1

复制
  using System;
  namespace AutoUnBox
  {
    class AutoBox {
      public void Example1() {
              TestAutoBox count = new TestAutoBox();
        int countValue = 0;
        for (long i = 0; i < 10; i++) {
          countValue += 0x2A;                       // no CS.RESOURCE.AUTOBOXING
       }
       count = countValue;
     }
   }
   class TestAutoBox {
 
     TestAutoBox(int intValue) {
       this.value1 = intValue;
     }
 
     private int value1 { set; get; }

     public static implicit operator TestAutoBox(int v) {
       return new TestAutoBox(v);
     }
   }
 }

在经修正的代码中,第 8 行的两个操作数均为循环中的内置整数,因此未报告任何问题。