我有以下方法:
public static bool EquivalentTo<T>(this T? current, T? compare)
where T : class
{
if (current is null && compare is null)
// both are null
return true;
if (current is null || compare is null)
// one is null, but not both
return false;
return current.Equals(compare);
}
IL Spy 在发布版本中提供以下 IL:
.method public hidebysig static
bool EquivalentTo<class T> (
!!T current,
!!T compare
) cil managed aggressiveinlining
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = (
01 00 00 00
)
.param type T
.custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(uint8) = (
01 00 01 00 00
)
// Method begins at RVA 0x4971
// Header size: 1
// Code size: 54 (0x36)
.maxstack 8
IL_0000: ldarg.0
IL_0001: box !!T
IL_0006: brtrue.s IL_0012
IL_0008: ldarg.1
IL_0009: box !!T
IL_000e: brtrue.s IL_0012
IL_0010: ldc.i4.1
IL_0011: ret
IL_0012: ldarg.0
IL_0013: box !!T
IL_0018: brfalse.s IL_0022
IL_001a: ldarg.1
IL_001b: box !!T
IL_0020: brtrue.s IL_0024
IL_0022: ldc.i4.0
IL_0023: ret
IL_0024: ldarg.0
IL_0025: box !!T
IL_002a: ldarg.1
IL_002b: box !!T
IL_0030: callvirt instance bool [System.Runtime]System.Object::Equals(object)
IL_0035: ret
} // end of method Extensions::EquivalentTo
我使用 Visual Studio 2022 和 64 位
.Net 8.0.100-preview.7.23376.3
进行编译。
我不明白为什么当泛型类型被限制为
class
并因此不能是值类型时会出现装箱。我错过了什么?
box !!T
br.true
或 br.false
序列对于结构始终是无操作。
由于 JITter 为所有 struct(值类型)泛型代码编译单独的代码,因此它可以看到 box 永远不会导致 null,因此它被省略。对于类(引用类型),它只执行正常的空检查。
如果您查看为结构和类生成的 JIT ASM 机器代码,您可以看到这一点。