在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仍然报道说这种方法是使用拳击。
有什么想法吗?
通过使用.NET Reflector反编译此方法,我们可以看到此方法实际上使用了box
IL指令。尽管您使用的是class
通用约束,编译器仍然会针对可验证性问题发出一条box指令。这里有更多的解释。
.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
}