C# 中的值类型与引用类型:内存大小解析

在 C# 中,类型可以被归类为值类型或引用类型,它们在内存中的存储和管理方式不同。了解这些差异对于优化程序性能和资源管理至关重要。

值类型 (Value Types)

值类型包括所有内置的数值类型(如 int, double 等)、char 类型、bool 类型,以及用户自定义的 struct 类型和 enum 类型。

内存占用

值类型实例占用的内存大小仅由其字段决定。例如,定义一个 Point 结构体:

public struct Point
{public int X;public int Y;
}

Point 结构体需要占用 8 字节的内存(假设 int4 字节),这正好是存储其两个 int 字段所需的内存。

实例化与赋值

值类型实例的赋值总是会进行实例复制。这意味着当你将一个值类型实例赋给另一个变量时,会创建该实例的一个全新副本。

Point p1 = new Point();
p1.X = 7;
Point p2 = p1;p1.X = 9;
Console.WriteLine(p1.X); // 输出 9
Console.WriteLine(p2.X); // 输出 7(原始值)

引用类型 (Reference Types)

引用类型包括类、数组、委托和接口类型(包括预定义的 string 类型)。

内存占用

引用类型需要为引用和对象单独分配存储空间。对象除了占用和字段一样多的字节数外,还需要额外的管理空间开销。这个开销至少需要 8 个字节来存储对象的类型信息和一些临时状态信息(如线程锁状态、垃圾回收固定等)。此外,根据.NET运行时是工作在32位还是64位平台上,每一个对象的引用都需要额外的 48 个字节的存储空间。

public class PointC
{public int X, Y;
}

对于 PointC 类,除了存储两个 int 字段所需的 8 字节外,还需要额外的空间来存储对象的引用和管理信息。

实例化与赋值

引用类型变量赋值只会复制引用,而不会复制对象实例。这意味着,当你将一个引用类型实例赋给另一个变量时,两个变量都指向同一个对象实例。

PointC pc1 = new PointC();
pc1.X = 7;
PointC pc2 = pc1;pc1.X = 9;
Console.WriteLine(pc1.X); // 输出 9
Console.WriteLine(pc2.X); // 输出 9(与 pc1 相同实例)

空引用 (Null Reference)

引用类型可以使用 null 来赋值,表示它并不指向任何对象。尝试访问 null 引用的成员会引发 NullReferenceException 异常。

PointC pc3 = null;
Console.WriteLine(pc3 == null); // 输出 true
// Console.WriteLine(pc3.X); // 未经处理的异常: System.NullReferenceException

总结

值类型和引用类型在 C# 中有着根本的不同,了解它们如何占用内存以及它们的行为对于编写高效且稳定的 .NET 应用程序至关重要。值类型提供了轻量级的数据结构,而引用类型则提供了更丰富的特性,如继承和接口实现。开发者应根据实际需要选择适当的类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/18913.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于APM32F407配置串口DMA收发没有数据的问题记录

一.问题环境 ​ 整活了一套APM32F407的板子,用了APM32F4xx_SDK_V1.4的标准外设库,正在搭建移植底层BSP框架串口部分,BSP底层配置逻辑是从STM32F407移植过来的。DMA发送时才使能通道及配置外设地址及缓存大小。 ​ 串口1DMA配置过程如下&…

leetcode 1270 向公司CEO汇报工作的所有人(postgresql)

需求 员工表:Employees ---------------------- | Column Name | Type | ---------------------- | employee_id | int | | employee_name | varchar | | manager_id | int | ---------------------- employee_id 是这个表的主键。 这个表中每一行中,e…

多个查询有同一个字段做关联,各个查询用临时表再用join 链接 拼接一个查询语句

查询自定日期活跃充值和总充值 TotalRecharge总金额字段 SELECT a.UserID, a.TotalRecharge, b.dayamount FROM ( SELECT i.UserID, a.TotalRecharge FROM qplogdb.user_inout_log_202405 AS i …

用于脑肿瘤分割的跨模态深度特征学习| 文献速递-深度学习肿瘤自动分割

Title 题目 Cross-modality deep feature learning for brain tumor segmentation 用于脑肿瘤分割的跨模态深度特征学习 01 文献速递介绍 作为最致命的流行病,脑肿瘤的研究越来越受到关注。本文研究了一种基于深度学习的自动分割胶质瘤的方法,称为脑…

utf8mb4_general_ci和utf8mb4_0900_ai_ci

utf8mb4_general_ci和utf8mb4_0900_ai_ci 在 MySQL 数据库中,字符集和排序规则(collation)决定了如何存储和比较字符串数据。utf8mb4 是 MySQL 中用于支持完整的 UTF-8 字符(包括表情符号和其他 4 字节字符)的一种字符…

筛斗数据:如何利用数据提取技术进行环境监测与预警

利用数据提取技术进行环境监测与预警,是现代环境管理中的一项重要手段。它通过高效地从多源数据中提取、分析关键信息,实现对环境状况的实时监测和潜在风险的早期预警。以下是几个具体步骤和方法,说明如何有效利用数据提取技术: …

raid 磁盘阵列

raid 磁盘阵列: **条带化存储:**数据分散在多个物理磁盘上的存储方式。利用多个磁盘并行读取和写入。 条带化的存储性能和读写性能是最好的。 磁盘的组成方式不同,也就是不同的raid级别: **raid 0(条带化存储&#x…

音视频开发_SDL入门

SDL是 “Simple DirectMedia Layer”的缩写,它是一个开源的项目。其主要用于游戏开发中的多媒体处理,如视频渲染,音频播放,鼠标/键盘控制等操作。 并且它是一个跨平台的多媒体库。也就是说它对外接供了一套统一的接口&#xff0c…

高级软件工程师带你解决MySQL死锁问题Deadlock found when trying to get lock实战案例全网唯一

高级软件工程师带你解决MySQL死锁问题Deadlock found when trying to get lock实战 前言 笔者我实际工作中,经常遇到mysql数据库死锁问题!CSDN上面也有很多大神刨析解决方法! 我在实际工作中的MySQL数据库架构很复杂,又涉及到主…

MT3045 松鼠接松果

思路: 求x的一个区间,使区间中的松果的最大y坐标和最小y坐标的差至少为D。若有多个区间,则取最小的那个。 即使用单调队列不断维护最大值和最小值。 首先L固定不动,R不断右移: 即若函数f(R)max[L,R]-min[L,R] >…

自建视频托管平台:MediaCMS

目录 1 MediaCMS简介1.1 介绍1.2 特性1.3 应用场景 2 安装配置2.1 安装1、安装2、汉化 2.2 一些常见配置 3 简单使用3.1 上传3.2 下载3.3 添加标题或者字幕3.4 通过Tag/Category实现视频/文件分类添加 Tag给任一资源分类 1 MediaCMS简介 1.1 介绍 MediaCMS是一个现代的&#…

Spring +SpringMVC+Mybatis项目详细构造

一,文档详解 1,web.xml配置 配置spring监听器: 指定spring配置文件的位置和名称,扫描会先扫描此文件,此文件中的扫描文档作为父类扫描,父类扫描不可访问子类扫描,子类扫描可访问父类扫描 &l…

LeetCode --- 399周赛

题目列表 3162. 优质数对的总数 I 3163. 压缩字符串 III 3164. 优质数对的总数 II 3165. 不包含相邻元素的子序列的最大和 一、优质数对的总数I 这里由于数据范围比较小,我们可以直接暴力枚举,代码如下 class Solution { public:int numberOfPairs…

JavaScript字符串方法

charAt() 方法:返回指定索引处的字符。 示例: let str "Hello World"; console.log(str.charAt(0)); // Output: "H" console.log(str.charAt(6)); // Output: "W"charCodeAt() 方法:返回指定索引处字符的 Un…

数组321

package demo; public class Goodtest { public static void main(String[] args) { Good arr[]new Good[3]; Good g1new Good("001","小米",5990,100); Good g2new Good("002","保温杯",227,100); Good g3new G…

5292A 物联网信号分析仪

5292A 物联网信号分析仪 —— 10MHz~6GHz —— 简述 5292A物联网信号分析仪是一款通用的矢量信号分析仪,频率范围覆盖 10MHz~6GHz,具有良好的频率、功率测量精度和稳定度;支持模拟与数字调制信号、全制式的通信标准…

【错误记录】HarmonyOS 运行报错 ( Failure[MSG_ERR_INSTALL_FAILED_VERIFY_APP_PKCS7_FAIL] )

文章目录 一、报错信息二、问题分析二、解决方案 一、报错信息 在 DevEco Studio 中 , 运行程序 , 编译时正常编译 , 但是在真机运行时 , 报如下错误 , 核心报错信息是 " Failure[MSG_ERR_INSTALL_FAILED_VERIFY_APP_PKCS7_FAIL] " ; 完整报错信息 : 05/29 10:58:55…

vue 微信公众号H5页面截取长图并分享给朋友

截图:使用dom-to-image 或者 html2canvas 分享:可以使用右上角分享 或者 自定义分享wx.updateAppMessageShareData 截图dom-to-image 并分享 请注意,dom-to-image库在将DOM元素转换为图片时可能不会包括所有的CSS样式,因为它是基于…

【机器学习300问】104、残差网络是怎么起作用的?

残差网络(Residual Network,简称ResNet)诞生是为了解决深度神经网络的训练困难性问题。深度神经网络在图像分类等任务上取得了重大突破,但随着网络层数的增加,训练变得更加困难。 一、神经网络深度过深会出现…

用docker搭建的Vulfocus镜像管理界面没有镜像可以拉取解决办法

ps:截止到今天2023.4.2,kali和vps的docker拉取的vulfocus镜像会有版本的区别,虽然都是拉取的最新版,vps上镜像为3个月以前,kali上为16个月以前,所以在修改 views.py 文件时,可能会发现文件内容不…