文章目录
1、分类回顾
- 值类型:内容存在栈内存
- 无符号:byte、ushort、uint、ulong
- 有符合:sbyte、short、int、long
- 浮点数:float、double、decimal
- 特殊:char、bool
- 枚举:enum
- 结构体:struct
- 引用类型:内容存在堆内存
- 字符串:string
- 数组:Array
- 类:class
- 接口:interface
- 委托
如何判断值类型和引用类型?
- 按 F12 进内部查看,是 class 就是引用类型,是 struct 就是值类型
2、语句块
2.1、关系图
命名空间
{
类、接口、结构体
{
函数、属性、索引器、运算符重载等(内部 类、接口、结构体)
{
条件分支、循环
}
}
}
2.2、分类
- 【上层语句块】:类、结构体
- 【中层语句块】:函数
- 【底层语句块】:条件分支、循环等
思考1:逻辑代码写在哪里?
- 函数、条件分支、循环;也就是中底层语句块中
思考2:变量可以申请在哪里?
- 上、中、底层都可以
- 上层:成员变量
- 中、底层:临时变量
3、变量生命周期
- 编程时大部分变量都是 【临时变量】
- 在中、底层声明的临时变量,语句执行结束时,没被记录的对象被回收或变成垃圾
- 值类型:被系统自动回收
- 引用类型:栈上用于存地址的空间被系统自动回收,堆中存储具体内容的空间变成垃圾,待下次GC回收
- 想要不被回收或者不变垃圾,就必须记录下来
- 在更高层记录
- 使用静态变量
3.1、假设某方法体内有如下变量声明
int num = 1;
string str = "xxx";
- 内存使用状态如下
3.1、该方法运行结束后
- 内存使用状态如下
4、结构体中的值和引用
- 结构体本身是值类型(前提:该结构体没有作为其他类的成员)
- 在结构体中的值:栈中存储值的具体内容
- 在结构体中的引用:堆中存储引用具体内容
- 引用类型始终存储在堆中,真正通过结构体使用其中的引用类型时只是顺藤摸瓜
4.1、有结构如下
struct Student
{
public int age;
public Test test;
}
class Test{ }
4.2、内存使用情况
5、类中的值和引用
- 类本身是引用类型
- 在类中的值,堆中存储具体的值
- 在类中的引用,堆中存储具体的值
- 总之,值类型跟大哥走,引用类型一根筋(死活存堆里)
5.1、有类如下
class Test
{
public int age;
public string str;
}
5.2、内存使用情况
6、数组中的存储规则
- 数组本身是引用类型
- 值类型数组:堆空间存具体内容
- 引用类型数组:堆空间存地址,再指向堆中存具体内容的空间
7、结构体继承接口(装箱拆箱)
- 利用里氏替换原则,用接口容器装载结构体存在装箱拆箱
7.1、有结构如下
interface ITest
{
int Value
{
get;
set;
}
}
struct MyTest : ITest
{
int value;
public int Value
{
get => value;
set => this.value = value;
}
}
7.2、内存使用情况
- 常规结构体
- 装箱拆箱