C#—值类型和引用类型
程序员文章站
2022-05-06 10:08:27
...
目录
一、概念
值类型:直接存储值,在栈上存储其值
应用类型:存储对其值的引用,在栈上存储地址,在堆上存储值
二、数据类型
三、二者的比较
|
值类型 |
引用类型 |
来源 |
继承自System.ValueType |
继承自System.Object |
用途 |
表示实际数据 |
表示指向存储在内存堆中的数据的指针或引用 |
数据存储位置 |
存储在内存的栈中 |
存储在内存的堆中,而内存单元中只存放堆中对象的地址 |
变量存放的类型 |
直接存放实际的数据 |
存放数据的地址,即对象的引用 |
保存位置上 |
变量直接把变量的值保存在堆栈中 |
变量把实际数据的地址保存在堆栈中,把实际数据则保存在堆中 |
继承性 |
密封的,不能作为其他任何类型的基类,可以单继承或多继承接口 |
一般都具有继承性 |
变量值 |
不可为Null,值类型都会自动初始化为0值 |
默认情况下,创建为Null值,表示指向任何托管堆的引用地址。对值为Null的引用类型的操作,都会抛出NullReferenceException异常 |
四、二者的联系
值类型和引用类型能够互相转换,即为装箱和拆箱操作:
装箱在值类型向引用类型转换时发生,将一个数据项(副本)从栈中自动复制到堆中的行为。
int i = 8;
object o = i; // 装箱 // 首先在堆中开辟出一片区域,再将 i 的一个副本放在该区域中。
// 所有引用都必须引用堆上的对象
拆箱在引用类型向值类型转换时发生,将一个数据项(副本)从堆中自动复制到栈中的行为。
int i = 8;
object o = i; // 装箱
i = (int)o; // 拆箱 // 此处使用强制类型转换(cast)
补充:
托管堆:是CLR(公共语言数据库)中自动内存管理的基础。初始化新进程时,运行时会为进程保留一个连续的地址空间区域,这个保留的地址空间被称为托管堆。