CS4L24——值类型和引用类型补充
CS4L24——值类型和引用类型补充
知识回顾
在C#中,所有的变量类型都会分为值类型和引用类型,分类如下:
值类型
- 无符号:
byte
,ushort
,uint
,ulong
- 有符号:
sbyte
,short
,int
,long
- 浮点数:
float
,double
,decimal
- 特殊:
char
,bool
- 枚举:
enum
- 结构体:
struct
引用类型
-
string
- 数组
-
interface
-
class
- 委托
查看值类型还是引用类型
两者的本质区别,值类型在栈内存上,引用类型在堆内存上
按 F12 可以进一个类型的内部查看,是 class
就是引用类型,struct
就是值类型
语句块
1 | 命名空间 |
- 上层语句块:类、结构体
- 中层语句块:函数
- 底层语句块:条件分支,循环
我们的逻辑代码写在:函数、条件分支、循环-中底层语句块中
我们的变量在上、中、底都能申明,其中:
- 上层语句块中:成员变量
- 中、底层语句块中:临时变量
变量的生命周期
编程时大部分都是临时变量,在中底层申明的临时变量(函数、条件分支、循环语句块等)
语句块执行结束,没有被记录的对象将被回收或变成垃圾
- 值类型:被系统自动回收
- 引用类型:栈上用于存储地址的内存被系统自动回收,堆中具体内容变成垃圾,待下次 GC 回收
想要不被回收或者不变垃圾,必须将其记录下来,如何记录:在更高层级记录或者使用静态全局变量记录
比如底层的代码块里定义的非静态变量就不能给更高级的代码用
1 | if (true) |
类似于这种代码,这种写法的 index
会反复被回收和加入,增加性能开销,同时每次循环的 index
都不会是同一个 index
:
1 | while (true) |
因此这种定义变量一般写在外面,而且每次循环的 index
都是同一个 index
1 | int index = 0; |
结构体中的值和引用
首先明确:值类型始终存储的都是数值,引用类型始终存储的都是地址,不管在堆里还是在栈里
结构体本身是值类型,前提是:该结构体没有作为其他类的成员
- 在结构体中的值,栈中存储值具体的内容
- 在结构体中的引用,栈存的是地址,堆中存储引用的具体内容
引用类型始终存储于堆中:真正通过结构体使用其中引用类型是只是顺藤摸瓜(顺着地址找到对应的堆内存)
类中的值和引用
类本身就是引用类型,在类中的值和引用,都是堆中存储值具体的内容
值类型在值类型里就存储在栈里,在引用类型里就在存储在堆里,引用类型都是存储在堆里
即使是分配了同一个连续房间(类,结构体),
值类型始终存储的都是数值,引用类型始终存储的都是地址(数据存储在堆里的另外一个房间内),不管在堆里还是在栈里
数组的存储规则
数组本身是引用类型
- 值类型数组,堆中房间存储具体内容
- 引用类型数组,堆中房间存储地址(数据存储在堆里的另外一个房间内)
结构体继承接口
利用里氏替换原则,用接口(引用类型)装载结构体(值类型)就会存在装箱拆箱!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 文KRIFE齐的博客!