一、类型
1、C#程序是一组类型声明。
2、通过实例化类型而创建的对象被称为类型的对象或类型的实例。
3、C#提供16种预定义类型,包括13种简单类型和3种非简单类型。
① 13种简单类型中包括11种数值类型(包括整数类型和浮点类型)和2种非数值类型。
表一 11种数值类型
类型名称 |
注释 |
整数类型 |
8种 |
sbyte |
8位有符号整数 |
byte |
8位无符号整数 |
short |
16位有符号整数 |
ushort |
16位无符号整数 |
int |
32位有符号整数 |
uint |
32位无符号整数 |
long |
64位有符号整数 |
ulong |
64位无符号整数 |
浮点类型 |
3种 |
float |
单精度浮点数 |
double |
双精度浮点数 |
decimal |
高精度小数类型,有效数字精度位28位。 |
表二 2种非数值类型
类型名称 |
注释 |
char |
Unicode字符类型 |
bool |
布尔类型 |
② 3种非简单类型
类型名称 |
注释 |
object |
所有其他类型的基类 |
string |
0个或多个Unicode字符所组成的序列 |
dynamic |
在使用动态语言编写的程序集时使用 |
③ C#有6种类型可以由用户自己创建,分别是 类类型(class),结构类型(struct),数组类型(array),枚举类型(enum),委托类型(delegate),接口类型(interface)。
二、栈和堆
1、栈
① 是一个内存数组,是一个后进先出(LIFO)的数据结构。
② 栈存储几种类型的数据:某些类型变量的值、程序当前的执行环境、传递给方法的参数。
③ 数据只能从栈的顶端插入和删除。
④ 把数据放到栈顶成为入栈(push)。
⑤ 从栈顶删除数据称为出栈(pop)。
2、堆
① 是一块内存区域,在堆里可以分配大块的内存用于存储某类型的数据对象。
② 堆与栈不同的是,堆里的内存能够以任意顺序存入和删除。
三、值类型与引用类型
类型除了决定了存储数据需要的内存大小以及组成该类型的数据成员,还决定了类型的对象在内存中的存储位置,于是类型又被分为两种,值类型和引用类型。
1、值类型:数据存放在栈里。
2、引用类型:引用存放在栈里,数据存放在堆里。
3、当数据是另一个对象的成员,存储方式会有些不同。
① 引用类型的对象的数据始终存放在堆里。
② 值类型的对象的数据或引用类型的引用可以存放在栈里,也可以存放在堆里,这依赖于实际环境。
如引用类型的实例S,它有两个成员,值类型成员A,引用类型成员B。
尽管成员A是值类型,但它也是引用类型的实例S的数据的一部分,所以存放在堆里。
而成员B是引用类型,它的数据部分会始终存放在堆里,它的引用部分因为也作为S的数据的一部分,所以也会被存放在堆里。
四、变量
1、分类
① 本地变量:在方法的作用域保存临时数据,不是类型的成员。
② 字段:保存和类型或类型实例相关的数据,是类型的成员。
③ 参数:用于从一个方法到另一个方法传递数据的临时变量,不是类型的成员。
④ 数组元素:通常是同类数据项构成的有序集合的一个成员,可以为本地变量,也可以为类型的成员。
2、无初始化语句的本地变量有一个未定义的值,在赋值之前不能使用,试图使用未定义的本地变量会导致编译器产生一条错误信息。
3、自动初始化:一些类型的变量如果在声明时没有初始化语句,那么会被自动设为默认值,而一些则不能。
表三 变量
变量类型 |
存储位置 |
是否自动初始化 |
本地变量 |
栈 或 栈和堆 |
否 |
类字段 |
堆 |
是 |
结构字段 |
栈或堆 |
是 |
参数 |
栈 |
否 |
数组类型 |
堆 |
是 |
4、多变量声明
① 多变量声明中的变量必须类型相同。
②变量名间必须用逗号分隔,可以在变量名后包含初始化语句。
5、静态类型和dynamic关键字
① 静态类型:变量的类型在编译的时候已经确定并且不能在运行时修改。
② dynamic关键字:代表一个特定的、实际的C#类型,它知道如何在运行时解析自身。在编译时,编译器不会对dynamic类型的变量进行类型检查,
而是,它会将与该变量以及与该变量的操作相关的所有信息打包。在运行时,这些信息将会被检查,以确保它与变量所代表的实际类型保持一致,
否则,将在运行时抛出异常。
6、可空类型
在某些情况下,特别是使用数据库的时候,你希望表示变量目前未保存有效的值。对于引用类型,可以把变量设置为null。但定义值类型的变量时,不管它的内容是否时有效的,
其内存都会进行分配。对于这种情况,可以使用一个布尔指示器来和变量关联,如果值有效,则设置为true,否则就设置为false,而用可空类型也可以来解决,可空类型允许创建可以标记为有效或无效的值类型,
这样就可以在使用它之前确定值的有效与否。