我四处寻找,但找不到答案。说我有这段代码:
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
而不是装箱。另外,我希望以满足值和引用类型的方式执行此操作。
答案 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
将始终给出错误的结果,并删除该框操作