通过C#从CLR提取装箱/拆箱值类型...
在装箱时:如果可空实例不是 null ,则CLR将从可空实例中取出值并将其装箱。换句话说,将 5的 Nullable 装箱到中,将装箱到值5的 boxed-Int32 中。
关于取消装箱:取消装箱只是获得对已装箱对象的未装箱部分的引用的 Action 。问题在于,装箱的值类型不能简单地拆箱为该值类型的可空版本,因为装箱的值中没有 bool 值hasValue 字段。因此,在将值类型取消装箱为可空版本时,CLR必须分配一个 Nullable 对象,将 hasValue 字段初始化为 true ,并将值字段设置为与该值相同的值。装箱的值类型。这会影响您的应用程序性能(拆箱过程中的内存分配)。
为什么Nullable类型的CLR团队要经历这么多麻烦?为什么不首先将它简单地装箱到Nullable 中?
最佳答案
我记得这种行为是最后一刻的变化。在.NET 2.0的早期测试版中,Nullable<T>
是“常规”值类型。将值null
的int?
装箱后,将其转换为带有 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/