Question

In NDepend 4 (v4.1.0.6871) I am using the default Design query "Boxing/unboxing should be avoided":

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

It is reporting the following method (Inspired by and stolen from Jon Skeet's MiscUtil) as using boxing:

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

I don't understand how this method is possibly using boxing. I am not using a cast anywhere.

I tried the following version just in case the null coalescing operator was using boxing somehow behind the scenes:

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

... but I had no luck with that either, NDepend still reported that the method was using boxing.

Any ideas?

Était-ce utile?

La solution

By decompiling this method with .NET Reflector we see that indeed this method is using the box IL instruction. Despite the fact that you are using the class generic constraint, the compiler still emits a box instruction for verifiability issue. More explanation on this 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 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top