C#类型基础Part1-值类型与引用类型
C#类型基础Part1-值类型与引用类型
- 参考资料
- 前言
- 值类型
- 引用类型
- 装箱和拆箱
参考资料
- 《.NET之美–.NET关键技术深入与解析》
前言
C#中的类型一共分为两类,一类是值类型(Value Type),一类是引用类型(Reference Type)。值类型和引用类型是以它们在计算机内存中是如何被分配来划分的。值类型包括了 结构 和 枚举,引用类型则包括了 类、接口、委托 等。还有一种特殊的值类型,称为简单类型,比如byte、int等,这些简单类型实际上是BCL基类库类型的别名。比如,声明一个int类型,实际上是声明一个 System.Int32 结构类型。因此,在 Int32 类型中定义的方法或属性,都可以在int类型上调用,比如:
123.Equals(2);
所有的值类型都隐式地继承自 System.ValueType 类型(注意 System.ValueType 本身是一个类类型)。之所以说是“隐式地”,是因为在C#代码中,是看不到这个继承关系的,这个关系只有通过MSIL代码才能看到。 System.ValueType 类型和所有的引用类型都继承自 System.Object 基类。
C#不支持多重继承,因为结构已经隐式地继承自ValueType,所以结构不支持继承
说明:
栈(stack)是一种 后进先出的数据结构,在内存中,变量会被分配在栈上来进行操作。堆(heap)是用于为==引用类型的实例(对象)==分配空间的内存区域,在堆上创建一个对象,会将对象的地址传给栈上的变量(反过来叫变量指向此对象,或者变量引用此对象)。
值类型
当声明一个值类型的变量的时候,变量本身包含了值类型的全部字段,该变量会被分配在线程堆栈(Thread Stack)上。
假如有下面这个值类型,代表了直线上的一点:
public struct ValPoint{public int x;public ValPoint(int x){this.x=x;}
}
当在程序中声明一个变量:
ValPoint vPoint1;
vPoint1.x=10;
Console.WriteLine(vPoint1.x);//输出10
上面代码中,因为变量已经包含了值类型的所有字段,所以已经可以进行操作,并且只有对变量进行操作(vPoint1.x=10),才会进行入栈。对变量进行操作,实际上是一系列入栈、出栈操作。
如果将ValPoint改为引用类型class,则会出现编译错误:使用了未赋值的局部变量“vPoint1”。除此之外,引用类型在运行时经常会抛出NullReferenceException异常。
如果不对vPoint1.x进行赋值,直接写Console.WriteLine(vPoint1.x),则会出现编译错误:使用了可能为赋值的字段x。这是因为.NET的一个约束:所有的元素使用前都必须初始化。比如下面语句也会引发这个错误:
int i;
Console.WriteLine(i);
虽然结构类型变量本身不需要像类一样使用new操作符创建一个实例(其本身就相当于一个实例),但如果要使用它的内部成员,则要在使用前对它进行赋值。结构还有一个特性:调用结构上的方法前,需要对其所有字段进行赋值。 修改ValPoint:
public struct ValPoint{public int x;public void Blank(){}
}
那么下面的代码将会发生编译错误:
ValPoint vPoint1;
vPoint1.Blank();//使用了未赋值的变量vPoint1
Console.WriteLine(vPoint1);//使用了未赋值的变量vPoint1
解决上述问题可以通过这样一种方式:编译器隐式地为结构类型创建无参数的构造函数。在这个构造函数中会对结构成员进行初始化,所有的值类型成员被赋予0或者相当于0的值,所有的引用类型被赋予null值。(因此,Struct类型不可以自行声明无参数的构造函数)。所以,可以通过隐式声明的构造函数去创建一个ValPoint类型变量:
ValPoint vPoint1=new ValPoint();
Console.WriteLine(vPoint1.x);//输出0
引用类型
当声明一个引用类型变量,并使用new操作符创建引用类型实例的时候,该引用类型的变量会被分配到线程栈上,变量保存了位于堆上的引用类型的实例的内存地址。变量本身不包含任何类型所定义的数据。如果仅仅声明一个变量,但不使用new操作符,由于在堆上还没有创建类型的实例,因此,变量值为null,即不指向任何对象。
如果有这样一个类,它依然代表直线上的一点:
public class RefPoint{public int x;public RefPoint(int x){this.x=x}public RefPoint(){}
}
当仅仅写下
RefPoint rPoint1;
它会在线程栈上创建一个不包含任何数据,也不指向任何对象(不包含内存地址)的变量。
而当使用new操作符时:
rPoint1=new RefPoint(1)
则会完成下面几件事:
- 在应用程序堆上创建一个引用类型对象的实例,并分配内存地址
- 自动传递该实例的引用给构造函数。(正因为如此,才可以使用
this来访问这个实例) - 调用该类型的构造函数。
- 返回该实例的引用(内存地址),赋值给人Point1变量
装箱和拆箱
简单来说,装箱就是将一个值类型转换为等价的引用类型。它的过程分为这样几步:
- 在堆上为新生成的对象实例分配内存。该对象实例包含数据,但没有名称。
- 将栈上值类型变量的值复制到堆上的对象中。
- 将堆上创建的对象的地址返回给引用类型变量。
装箱实例代码如下:
int i=1;
Object boxed=i;
Console.WriteLine("Boxed Point:"+boxed);
拆箱则是将一个已装箱的引用类型转换为值类型:
int i=1;
Object boxed=i;
int j;
j=(int)boxed;
Console.WriteLine("UnBoxed Point: " + j);
需要注意的是:拆箱操作需要显示声明拆箱后转换的类型。它分为两步来完成
- 获取已装箱的对象的地址。
- 将值从堆上的对象中复制到堆栈上的值变量中。
可见,装箱和拆箱需要反复在堆上进行操作,因此,在程序中应该尽量避免无意义的装箱和拆箱。
相关文章:
C#类型基础Part1-值类型与引用类型
C#类型基础Part1-值类型与引用类型 参考资料前言值类型引用类型装箱和拆箱 参考资料 《.NET之美–.NET关键技术深入与解析》 前言 C#中的类型一共分为两类,一类是值类型(Value Type),一类是引用类型(Reference Type)…...
被上市公司预判的EPS增速分析
EPS增速对二级市场投资和估值有着很显著的影响,上市公司显然也知道这一点。对于想要做市值管理的上市公司来说,调节EPS增速比调节EPS更加有效。因此《穿透财报:读懂财报中的逻辑与陷阱》中的作者在第四章正式提出了二级市场财务分析中的额动态…...
快速入门了解Ajax
博客主页:音符犹如代码系列专栏:JavaWeb关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Ajax的初识 意义:AJAX(Asynchronous JavaScript and…...
FPGA开发——呼吸灯的设计
一、原理 呼吸灯的原理主要基于PWM(脉冲宽度调制)技术,通过控制LED灯的占空比来实现亮度的逐渐变化。这种技术通过调整PWM信号的占空比,即高电平在一个周期内所占的比例,来控制LED灯的亮度。当占空比从0%逐渐变化到1…...
【数据结构】二叉树链式结构——感受递归的暴力美学
前言: 在上篇文章【数据结构】二叉树——顺序结构——堆及其实现中,实现了二叉树的顺序结构,使用堆来实现了二叉树这样一个数据结构;现在就来实现而二叉树的链式结构。 一、链式结构 链式结构,使用链表来表示一颗二叉树…...
开始尝试从0写一个项目--后端(三)
器材管理 和员工管理基本一致,就不赘述,展示代码为主 新增器材 表设计: 字段名 数据类型 说明 备注 id bigint 主键 自增 name varchar(32) 器材名字 img varchar(255) 图片 number BIGINT 器材数量 comment VARC…...
2024年7月解决Docker拉取镜像失败的实用方案,亲测有效
在Ubuntu 16.04、Debian 8、CentOS 7系统中,若遇到Docker拉取镜像失败的问题,以下是一些亲测有效的解决方案: 配置加速地址 首先,创建Docker配置目录:sudo mkdir -p /etc/docker然后,编辑daemon.json文件…...
基于内容的音乐推荐网站/基于ssm的音乐推荐系统/基于协同过滤推荐的音乐网站/基于vue的音乐平台
获取源码联系方式请查看文末🍅 摘 要 随着信息化时代的到来,系统管理都趋向于智能化、系统化,音乐推荐网站也不例外,但目前国内的有些公司仍然都使用人工管理,公司规模越来越大,同时信息量也越来越庞大&…...
STM32智能工业监控系统教程
目录 引言环境准备智能工业监控系统基础代码实现:实现智能工业监控系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景:工业监控与优化问题解决方案与优化收尾与总结 1. 引言 智能工业监控系统通…...
WEB渗透Web突破篇-SQL注入(MYSQL)
注释符 # -- 注意这里有个空格 /* hello */ /*! hello */ /*!32302 10*/ MYSQL version 3.23.02联合查询 得到列数 order by或group by 不断增加数字,直到得到报错响应 1 ORDER BY 1-- #True 1 ORDER BY 2-- #True 1 ORDER BY 3-- #True 1 ORDER BY 4-- #Fal…...
PDF解锁网站
https://smallpdf.com/cn/unlock-pdfhttps://smallpdf.com/cn/unlock-pdfhttps://www.freemypdf.comhttps://www.freemypdf.com...
【Redis】主从复制分析-基础
1 主从节点运行数据的存储 在主从复制中, 对于主节点, 从节点就是自身的一个客户端, 所以和普通的客户端一样, 会被组织为一个 client 的结构体。 typedef struct client {// 省略 } client;同时无论是从节点, 还是主节点, 在运行中的数据都存放在一个 redisServer 的结构体中…...
Transformer自然语言处理实战pdf阅读
一.第一章 欢迎来到transformer的世界 1.解码器-编码器框架 在Transformer出现之前,NLP的最新技术是LSTM等循环架构。这些架 构通过在神经网络连接使用反馈循环,允许信息从一步传播到另一 步,使其成为对文本等序列数据进行建模的理想选择。如…...
Python 高阶语法
前言: 我们通过上篇文章学习了Python的基础语法,接下来我们来学习Python的高阶语法 1.初识对象 在Python中我们可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的 面向对象包含 3 大主要特性: 封装 继承 …...
开始尝试从0写一个项目--前端(三)
器材管理板块 添加器材管理导航 src\views\home\Home.vue src\router\index.js src\views\equipment\Equipment.vue <template><div>hello!</div></template> 测试 搜索导航分页查询 src\views\equipment\Equipment.vue <template><div&…...
Visual stdio code 运行C项目环境搭建
参考 [1]VS Code 配置 C/C 编程运行环境(保姆级教程)_visual studio code c配置-CSDN博客 [2]最新VS code配置C/C环境(tasks.json, launch.json,c_cpp_properties.json)及运行多个文件、配置Cmake_vscode launch.json如何配置-CSDN博客 先装visual stdi…...
免杀笔记 -->API的整理Shellcode加密(过DeFender)
最近更新频率明显下降我懒,那么今天就来记录一下我们的一些常用的API的整理以及ShellCode的加密。 1.WinAPI整理 问我为什么要整理? 就是用起来的时候要左翻右翻 :: 烦死了 1.VirtualAlloc VirtualAlloc(NULL,sizeof(buf),MEM_…...
Stable Diffusion 使用详解(3)---- ControlNet
背景 炼丹师在AI绘画的过程中,由于Stable Diffusion的原理是水滴式的扩散作图原理,其实在前面也有提到,他的发挥是‘不稳定’的,因为你没有办法做到精确控制,只能说是大致符合你的预期。你不能总依赖抽卡固定随机数种…...
pythonGame-实现简单的贪食蛇游戏
通过python简单复现贪食蛇游戏。 使用到的库函数: import pygame import time import random 游戏源码: import pygame import time import randompygame.init()white (255, 255, 255) yellow (255, 255, 102) black (0, 0, 0) red (213, 50, 80…...
2024年软件系统与信息处理国际会议(ICSSIP 2024)即将召开!
2024年软件系统与信息处理国际会议(ICSSIP 2024)将于2024年10月25-27日在中国昆明举行。引领技术前沿,共谋创新未来。ICSSIP 2024将汇聚来自世界各地的专家学者,他们将在会上分享最新的研究成果、技术突破及实践经验。会议议题涵盖…...
Linux SSH身份验证全解析:从密码到证书的六种方法与实践指南
1. SSH身份验证:守护远程访问的第一道门在Linux世界里,SSH(Secure Shell)就是那把打开远程服务器大门的钥匙。无论是管理云服务器、部署应用,还是进行日常运维,我们几乎每天都在和它打交道。但很多人可能没…...
LunaTranslator完整指南:5步掌握视觉小说实时翻译技巧
LunaTranslator完整指南:5步掌握视觉小说实时翻译技巧 【免费下载链接】LunaTranslator 视觉小说翻译器 / Visual Novel Translator 项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator 想要畅玩日文视觉小说却苦于语言障碍?LunaT…...
基于SpringBoot+Vue的CRM客户管理系统毕设
博主介绍:✌ 专注于Java,python,✌关注✌私信我✌具体的问题,我会尽力帮助你。一、研究目的本研究旨在构建一个基于Spring Boot与Vue框架的CRM客户管理系统以解决传统客户关系管理中存在的信息孤岛现象与业务流程低效问题。当前企业客户管理普遍面临数据…...
基于谐波补偿的多环路控制双向DC-AC逆变器建模
目录 手把手教你学Simulink——基于谐波补偿的多环路控制双向DC-AC逆变器建模 一、背景与挑战 1.1 为什么需要“谐波补偿多环路”? 1.2 核心痛点与设计目标 二、系统架构与核心控制推导 2.1 整体架构:主环路 谐波补偿环路的“分工合作” 2.2 核心…...
别再盲目缩放PGA了!土木工程师必看的地震动调整实战指南(附Python代码)
土木工程师的地震动调整实战指南:从原理到Python实现 地震动调整是结构抗震分析中的关键环节,却常被简化为机械的PGA缩放操作。这种粗放的处理方式可能导致分析结果严重偏离实际地震响应,给工程安全埋下隐患。本文将带您深入理解地震动调整的…...
开源本地AI API网关:统一管理Ollama等模型,简化LLM应用开发
1. 项目概述:一个开源的本地AI API网关最近在折腾本地大语言模型(LLM)的朋友,估计都遇到过类似的烦恼:模型装好了,界面也跑起来了,但想把它集成到自己的应用里,或者想用一套统一的接…...
JoyCon-Driver:让Switch手柄在Windows上重获新生的完整方案
JoyCon-Driver:让Switch手柄在Windows上重获新生的完整方案 【免费下载链接】JoyCon-Driver A vJoy feeder for the Nintendo Switch JoyCons and Pro Controller 项目地址: https://gitcode.com/gh_mirrors/jo/JoyCon-Driver 你是否曾经想过,让闲…...
【紧急预警】NotebookLM在广义相对论语境下的概念漂移现象:基于57篇PRL论文的偏差审计报告
更多请点击: https://intelliparadigm.com 第一章:【紧急预警】NotebookLM在广义相对论语境下的概念漂移现象:基于57篇PRL论文的偏差审计报告 现象复现与基准测试协议 我们在标准LIGO-PRL语料集(v2.3)上对NotebookLM…...
JetBrains IDE试用期重置技术全解析:从原理到实战的开发者指南
JetBrains IDE试用期重置技术全解析:从原理到实战的开发者指南 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 在JetBrains IDE生态系统中,试用期管理是每个开发者都会面临的实际问题。ide…...
如何轻松获取九大网盘直链下载地址:LinkSwift完整使用指南
如何轻松获取九大网盘直链下载地址:LinkSwift完整使用指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / …...
