八、值类型
8.1 结构
- 避免可变的值类型
- 若要修改值类型的变量,需要返回新的值类型,而不是直接修改自身
- 可以包含字段、属性、方法、构造器
8.1.1 结构的初始化
- 不允许自定义无参构造器
- 自定义的无参构造可能不会将所有成员都初始化
- 确保结构的全默认值有效,即值类型为0,引用类型为null
- 编译器会自动产生默认构造,将所有值初始化为默认值
- 当使用有后备字段的属性定义值类型并需要初始化时
- 所有字段都需要先进行初始化,才能访问this
- 能访问this,才能操作属性
- 不允许字段初始化器,即直接声明时赋值
8.1.2 值类型的继承和接口
- 所有值类型都隐式密封
- 值类型可以实现接口,例如IComparable
8.2 装箱与拆箱
8.2.1 装箱
- 将值类型转化为引用类型
- 装箱过程
- 在堆上分配内存
- 将栈上保存的值类型的数据复制到堆上
- 转换结果是对堆上新存储位置的引用
8.2.2 拆箱
int number = 42;
object thing;
double bigNumber;
thing = number;
bigNumber = (double)(int)thing;
string text = (IFormattable)thing.ToString("X",null);
8.3 枚举
8.3.1 枚举的特征
- 可由开发者声明的值类型
- 在编译时声明一组可以通过名称来引用的常量值,使代码更易读
- 枚举只不过是基础类型上的一组名称
8.3.2 定义枚举类型
- 默认对应的整型值从0开始
- 枚举总有一个基础类型
- 默认为int
- 可使用类似继承语法指定其他类型作为基础类型
enum ConnectionState:short
{
Disconnected,
Connecting =10,
Connected
}
8.3.3 枚举类型与基础类型的转化
- 整型值和枚举类型之间转换都需要显式转换
- 在没有对应的枚举值的前提下也允许转型
- 例如,某一枚举值为0~2,40也可成功转型为该枚举类型
8.3.4 枚举和字符串之间的转换
- 枚举转换为字符串
- 字符串转枚举
- Enum.Parse( typeof(枚举类型), “枚举标识符”)
- 需要本地化时应避免枚举和字符串之间的直接转换
8.3.5 位标识枚举
- 与普通枚举的区别
- 枚举值可以进行组合,组合后的值与其他枚举值仍然互斥
- 类型名称一般用复数
- 用 [Flags] 修饰
- 例如,[Flags] enum ConnectionStates { }
- FlagsAttribute标记改变了ToString()和Parse()方法
- 用位运算OR对多个枚举值组合
- 用位运算AND对枚举值进行判断
- 例如,一个读写的组合枚举,通过 “读写&读” 的bool结果判断是否具有读属性