通过C#从CLR提取装箱/拆箱值类型...

在装箱时:如果可空实例不是 null ,则CLR将从可空实例中取出值并将其装箱。换句话说,将 5的 Nullable 装箱到中,将装箱到值5的 boxed-Int32 中。

关于取消装箱:取消装箱只是获得对已装箱对象的未装箱部分的引用的 Action 。问题在于,装箱的值类型不能简单地拆箱为该值类型的可空版本,因为装箱的值中没有 bool 值hasValue 字段。因此,在将值类型取消装箱为可空版本时,CLR必须分配一个 Nullable 对象,将 hasValue 字段初始化为 true ,并将字段设置为与该值相同的值。装箱的值类型。这会影响您的应用程序性能(拆箱过程中的内存分配)。

为什么Nullable类型的CLR团队要经历这么多麻烦?为什么不首先将它简单地装箱到Nullable 中?

最佳答案

我记得这种行为是最后一刻的变化。在.NET 2.0的早期测试版中,Nullable<T>是“常规”值类型。将值nullint?装箱后,将其转换为带有 bool 标志的装箱的int?。我认为他们决定选择当前方法的原因是一致性。说:

int? test = null;
object obj = test;
if (test != null)
   Console.WriteLine("test is not null");
if (obj != null)
   Console.WriteLine("obj is not null");
在前一种方法中(box null-> boxed Nullable<T>),您不会得到“test not not null”,但会得到“object is not null”,这很奇怪。
此外,如果他们在boxed-Nullable<T>处加上了可为空的值,则:
int? val = 42;
object obj = val;

if (obj != null) {
   // Our object is not null, so intuitively it's an `int` value:
   int x = (int)obj; // ...but this would have failed.
}
除此之外,我相信当前行为对于诸如可为空的数据库值(请考虑使用SQL-CLR ...)之类的场景来说是非常有意义的。

澄清:
提供可空类型的全部目的是使处理没有意义的变量变得容易。他们不想提供两种不同的,不相关的类型。 int?的行为应大致类似于简单的int。这就是C#提供提升的运算符的原因。

这不是真的。 CLR将必须在堆栈上分配内存,以保存变量是否为空。为额外的 bool 变量分配空间没有性能问题。

关于c# - 装箱/取消装箱可空类型-为什么要执行此操作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1387597/

10-13 03:15