NDepend CQL报告方法错误地使用Boxing / Unboxing

时间:2013-08-03 06:36:03

标签: c#-4.0 generics boxing ndepend

在NDepend 4(v4.1.0.6871)中我使用默认的设计查询“应该避免使用装箱/拆箱”:

warnif percentage > 5 from m in Application.Methods where
    m.IsUsingBoxing ||
    m.IsUsingUnboxing
select new { m, m.NbLinesOfCode, m.IsUsingBoxing, m.IsUsingUnboxing }

它使用拳击报告以下方法(受Jon Skeet MiscUtil的启发和偷窃):

public static void ThrowIfNull<T>(this T target, string name) where T : class
{
  if (target == null)
  {
    throw new ArgumentNullException(name ?? string.Empty);
  }
}

我不明白这种方法怎么可能使用拳击。我没有在任何地方使用演员。

我尝试了以下版本,以防空合并操作符在幕后以某种方式使用装箱:

public static void ThrowIfNull<T>(this T target, string name) where T : class
{
  if (target == null)
  {
    throw new ArgumentNullException(name);
  }
}

...但我也没有运气,NDepend仍然报告该方法使用拳击。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

通过使用.NET Reflector反编译此方法,我们发现这个方法确实使用了box IL指令。尽管您正在使用class泛型约束,但编译器仍会针对可验证性问题发出一个框指令。关于此here的更多解释。

.method public hidebysig static void ThrowIfNull<class T>(!!T target, string name) cil managed
{
    .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
    .maxstack 2
    .locals init (
        [0] bool flag)
    L_0000: nop 
    L_0001: ldarg.0 
    L_0002: box !!T   <-----------
    L_0007: ldnull 
    L_0008: ceq 
    L_000a: ldc.i4.0 
    L_000b: ceq 
    L_000d: stloc.0 
    L_000e: ldloc.0 
    L_000f: brtrue.s L_0022
    L_0011: nop 
    L_0012: ldarg.1 
    L_0013: dup 
    L_0014: brtrue.s L_001c
    L_0016: pop 
    L_0017: ldsfld string [mscorlib]System.String::Empty
    L_001c: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string)
    L_0021: throw 
    L_0022: ret 
}