当泛型类型限制为类时,CIL 显示“box”操作

问题描述 投票:0回答:1

我有以下方法:

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
并因此不能是值类型时会出现装箱。我错过了什么?

c# roslyn cil boxing .net-8.0
1个回答
0
投票

box !!T
br.true
br.false
序列对于结构始终是无操作。

由于 JITter 为所有 struct(值类型)泛型代码编译单独的代码,因此它可以看到 box 永远不会导致 null,因此它被省略。对于类(引用类型),它只执行正常的空检查。

如果您查看为结构和类生成的 JIT ASM 机器代码,您可以看到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.