通过 C# 从 CLR 中提取有关装箱/拆箱值类型的信息...
关于装箱:如果可空实例不是null,CLR 从可为 null 的实例中取出值并将其装箱。换句话说可空 值为5被装箱成盒装-Int32值为 5。
关于拆箱:拆箱只是获取对装箱对象的拆箱部分的引用的操作。问题是装箱值类型不能简单地拆箱为该值类型的可为空版本,因为装箱值没有布尔值场在其中。因此,当将值类型拆箱为可为 null 的版本时,CLR 必须分配一个可空 对象,初始化hasValue字段到true,并设置value字段的值与装箱值类型中的值相同。这会影响您的应用程序性能(拆箱期间的内存分配)。
为什么 CLR 团队在 Nullable 类型上经历了这么多麻烦?为什么不首先将其简单地装入 Nullable 中?
我记得这种行为是最后一刻的改变。在 .NET 2.0 的早期测试版中,Nullable<T>
是“正常”值类型。拳击一null
valued int?
把它变成了盒装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");
在前一种方法中(框null
-> 盒装Nullable<T>
),你不会得到“test is 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...)
澄清:
提供可为 null 类型的全部目的是使处理没有有意义值的变量变得容易。他们不想提供两种不同的、不相关的类型。一个int?
应该表现得或多或少像一个简单的int
。这就是 C# 提供提升运算符的原因。
因此,当将值类型拆箱为可为 null 的版本时,CLR 必须分配一个Nullable<T>
对象,将 hasValue 字段初始化为 true,并将 value 字段设置为与装箱值类型中的值相同。这会影响您的应用程序性能(拆箱期间的内存分配)。
这不是真的。 CLR 必须分配内存on stack保存变量,无论它是否可为空。为额外的布尔变量分配空间不存在性能问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)