【问题标题】:Does Performing a Null Check on a Generic Cause Boxing? [duplicate]是否对通用原因进行空值检查? [复制]
【发布时间】:2018-07-19 01:06:10
【问题描述】:

我环顾四周,找不到答案。假设我有这个代码:

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

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

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

【问题讨论】:

标签: c# .net boxing


【解决方案1】:

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

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

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

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

【讨论】:

  • 太棒了。来自可敬的斯基特先生的回答。把它从技术清单上划掉。 :) 感谢您抽出宝贵时间回答!
猜你喜欢
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 2011-09-24
  • 2022-12-31
  • 2018-12-23
相关资源
最近更新 更多