2013-08-03 2 views
1

В NDepend 4 (v4.1.0.6871) Я использую запрос Дизайн по умолчанию «Бокс/распаковка следует избегать»:NDepend CQL сообщает методы, с помощью бокса/распаковка неправильно

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

Он сообщает следующий метод (Вдохновленный и украденные у Джона Скита 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

Декомпилировав этот метод с помощью .NET Reflector, мы видим, что действительно этот метод использует команду ILS box. Несмотря на то, что вы используете общее ограничение 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 
}