在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仍然报告该方法使用拳击。
有什么想法吗?
答案 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
}