c# - 装箱/拆箱可空类型 - 为什么要执行此操作?

标签 c# .net clr nullable

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

关于装箱:如果可为空的实例不是null,CLR 会从可为空的实例中取出值并将其装箱。换句话说,值为 5Nullable < Int32 > 装箱到值为 5 的 boxed-Int32 中。

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

为什么 CLR 团队要为 Nullable 类型经历这么多麻烦?为什么不首先将它简单地装入 Nullable < Int32 > 中?

最佳答案

我记得这种行为是最后一刻的改变。在 .NET 2.0 的早期测试版中,Nullable<T>是一个“正常”值类型。拳击null有值(value)int?变成盒装int?带有 bool 标志。我认为他们决定选择当前方法的原因是一致性。说:

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 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...)这样的场景非常有意义


澄清:

提供可空类型的全部意义在于可以轻松处理没有有意义值的变量。他们不想提供两种不同的、不相关的类型。一个int?应该表现得或多或少像一个简单的 int .这就是 C# 提供提升运算符的原因。

So, when unboxing a value type into a nullable version, the CLR must allocate a Nullable<T> object, initialize the hasValue field to true, and set the value field to the same value that is in the boxed value type. This impacts your application performance (memory allocation during unboxing).

这不是真的。 CLR 必须在堆栈上 分配内存来保存变量,无论它是否可为空。为额外的 bool 变量分配空间不存在性能问题。

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

相关文章:

c# - 用于 webm 视频转换的 API

Java 与 .NET 性能

c# - .net 中的原始类型

c# - 查询以检索每个操作的最新状态

c# - 将 C++ 结构编码(marshal)到 C# 的最有效方法是什么?

c# - 正确使用迭代 block

c# - 什么会导致 FindControl() 抛出 NullReferenceException?

java - 不需要操作系统的.NET CLR?

.net - "Memory Pressure"是什么意思?

C# DataGridView 虚拟模式 : Enable sorting