是否对通用原因拳击执行空检查?

时间:2018-02-08 12:45:49

标签: c# .net boxing

我四处寻找,但找不到答案。说我有这段代码:

class Command<T> : ICommand<T>
{
    public void Execute(T parameter)
    {
        var isNull = parameter == null;
        // ...
    }
}

T可以是任何类,甚至是Nullable<>。如果T是值类型,执行上述检查会导致装箱吗?我的理解是,这与调用ReferenceEquals相同,后者需要两个object个参数,如果T是值类型,如果我理解正确的话,其中任何一个都会导致装箱。

如果以上确实导致拳击,是否有更优选的方法来做到这一点而不会导致框发生?我知道有default(T)但是int的情况是0,我希望看看这个值是null而不是装箱。另外,我希望以满足值和引用类型的方式执行此操作。

1 个答案:

答案 0 :(得分:5)

不 - 至少不是我的理解。如果T是不可为空的值类型,则JIT编译器会将parameter == null检查有效地替换为false;没有执行执行时检查。

这是只有JIT编译器才能执行的优化,因为C#编译器只生成一种形式的代码。例如,为您的样本生成的IL是:

IL_0000:  ldarg.1
IL_0001:  box        !T
IL_0006:  ldnull
IL_0007:  ceq

这似乎实际上执行了拳击 - 但我相信一个体面的JIT编译器发现当T不可为空时,ceq将始终给出错误的结果,并删除该框操作