可空类型装箱/拆箱 - 为什么要这样实现?

2024-03-06

通过 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(使用前将#替换为@)

可空类型装箱/拆箱 - 为什么要这样实现? 的相关文章

随机推荐

  • 如何使用 Laravel 和 Eloquent 查询两个日期?

    我正在尝试创建一个报告页面 显示从特定日期到特定日期的报告 这是我当前的代码 now date Y m d reservations Reservation where reservation from now gt get 这在普通 SQ
  • 如何在 Django 1.7 的表单模型中获取当前登录的用户 ID?

    假设我有一个显示歌曲的网页 假设有公共歌曲和私人歌曲 公开歌曲是所有人都可以看到的 而私人歌曲是某个用户自己创建的 只有他自己可以看到的歌曲 所以用户应该只看到那些具有owner id NULL和owner id current logge
  • Ruby:将变量合并到字符串中

    我正在寻找一种更好的方法 在 Ruby 中将变量合并到字符串中 例如 如果字符串类似于 The animal action the second animal 我有变量animal action and second animal 将这些变
  • Tensorflow 基本示例错误:CUBLAS_STATUS_NOT_INITIALIZED

    您好 我正在尝试安装并运行tensorflow 1 0 我正在使用以下指南https www tensorflow org get started mnist beginners https www tensorflow org get s
  • 缺少“访问控制允许来源”。我的下一步应该是什么?

    我想从这里提取收益率曲线数据 下面的 get 请求返回 200 正常 状态代码 但也显示一条控制台注释 指出跨域请求被阻止 因为缺少 CORS 标头 Access Control Allow Origin get http www trea
  • 如何从 PHP 中的 json_decode 访问嵌套数组?

    我花了几个小时在这上面 并且在 stackoverflow 上阅读了很多答案 但没有一个有帮助 到目前为止我所能做的就是打印集市广场 克利夫登对于这个例子 obj json decode data obj obj 0 print obj g
  • 如何使用 python 的 PIL 以一定角度绘制文本?

    使用 Python 我希望能够使用 PIL 以不同角度绘制文本 例如 假设您正在钟面周围绘制数字 号码3会按预期出现 而12我们将逆时针旋转 90 度来绘制 因此 我需要能够从许多不同的角度绘制许多不同的弦 将文本绘制到临时空白图像中 旋转
  • 不同进程的内存地址相同

    我只是不明白为什么这段代码会这样工作 而不是我期望的 include
  • LINQ 与 FoxPro?

    有没有合理的方法使用 LINQ 访问 FoxPro 数据库 我刚刚完成实施工作 http linqtovfp codeplex com http linqtovfp codeplex com
  • Android:事件 ACTION_POWER_CONNECTED 未发送到我的 BroadcastReceiver

    我想在手机插入充电器后做一些事情 所以我 已创建ChargingOnReciever public class ChargingOnReceiver extends BroadcastReceiver public void onRecei
  • Flash 消息无法正常工作express/nodejs/ejs

    闪存消息似乎不起作用 我想我错过了一些非常明显的东西 但我已经研究了一个小时 但我仍然不知道为什么它不起作用 我的中间件 Session middleware app use session secret stuffedbagels res
  • 通过嵌套 tf.map_fn 反向传播梯度

    我想在每个向量上映射一个 TensorFlow 函数 该向量对应于具有维度的矩阵中每个像素的深度通道 批量大小 H W n 通道 换句话说 对于每个尺寸的图像H x W我在批次中拥有 我提取一些特征图F k 其数量为n channels 具
  • 无法在主线程上启动处理程序

    我正在开发 jar api 以从 Unity3D 读取 Google Fit 数据 我现在面临的问题是 当我想执行这段代码时 private void buildFitnessClient mClient new GoogleApiClie
  • 强制用户在首次使用 Devise 登录时重置密码

    预计到达时间最后更新为我当前的解决方案 我希望能够为高价值用户手动创建帐户 这意味着我们必须为他们生成密码并让他们在首次登录时更改密码 我找到了执行此操作的解决方案here https stackoverflow com questions
  • Cython setup.py 找不到已安装的 Visual C++ 构建工具

    我正在尝试使用此 setup py 文件构建我的 cython 代码 from distutils core import setup from Cython Build import cythonize import numpy as n
  • C# Linq 在嵌套数组对象中查找特定项

    我正在使用 asp net core webapi 和 azure cosmosdb 开发一个应用程序 我需要从对象列表中找到一个项目 我对 linq 没有经验 在下面的 json 中 我需要找到一个拥有 learnerId 123 的扇区
  • php xpath 与 text() 和 SimpleXMLElement->xpath 不符合 xpath 预期结果

    我正在尝试获取 td span 的所有文本节点 我正在尝试使用 xpath td span text 问题是它返回每个文本元素的所有文本节点 这里有两个 193 和 120 它返回 193120 两次 而不是单独元素中的 193 和 120
  • 获取 numpy 稀疏矩阵行的范数

    我有一个通过使用 Sklearn 的 TfidfVectorizer 对象获得的稀疏矩阵 vect TfidfVectorizer sublinear tf True max df 0 5 analyzer word vocabulary
  • 如何有效地编码/解码压缩的位置描述?

    我正在为日本象棋变体编写一个表库 为了索引表基数 我将每个国际象棋位置编码为整数 在编码步骤之一中 我对棋盘上棋子的位置进行编码 由于实际方法有点复杂 我就简单地解释一下这个问题 编码 在残局桌面中 我有 比方说 六个不同的棋子 我想将它们
  • 可空类型装箱/拆箱 - 为什么要这样实现?

    通过 C 从 CLR 中提取有关装箱 拆箱值类型的信息 关于装箱 如果可空实例不是null CLR 从可为 null 的实例中取出值并将其装箱 换句话说可空 值为5被装箱成盒装 Int32值为 5 关于拆箱 拆箱只是获取对装箱对象的拆箱部分