【发布时间】:2021-03-19 05:00:40
【问题描述】:
给出以下IsNull 方法:
public class Field<T>
{
public static bool IsNull(T value) => value is null; // or: => value == null;
}
T 是值类型时是否有装箱?如果答案是肯定的,不装箱怎么实现?编辑:它应该正确处理可空类型,例如int?。
编辑2:
使用ILDASM 表明value is null 和value == null 存在拳击:
.method public hidebysig static bool IsNull(!T 'value') cil managed
{
// Code size 15 (0xf)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: box !T
IL_0007: ldnull
IL_0008: ceq
IL_000a: stloc.0
IL_000b: br.s IL_000d
IL_000d: ldloc.0
IL_000e: ret
} // end of method Field`1::IsNull
但是,下面的代码:
public class Field
{
public static bool IsNull(int? value)
{
return value == null;
}
}
不装箱会编译成如下:
.method public hidebysig static bool IsNull(valuetype [System.Runtime]System.Nullable`1<int32> 'value') cil managed
{
// Code size 16 (0x10)
.maxstack 2
.locals init (bool V_0)
IL_0000: nop
IL_0001: ldarga.s 'value'
IL_0003: call instance bool valuetype [System.Runtime]System.Nullable`1<int32>::get_HasValue()
IL_0008: ldc.i4.0
IL_0009: ceq
IL_000b: stloc.0
IL_000c: br.s IL_000e
IL_000e: ldloc.0
IL_000f: ret
} // end of method Field::IsNull
所以编译器确实特别对待Nullable<>,但不在泛型类上下文中。
【问题讨论】:
-
我不认为它涉及拳击。而且,int?不是引用类型,所以我相信编译器以一种特殊的方式处理它的可空性,因此,很难说这里是否涉及到装箱。
-
@A.T.请看看我更新的问题。