C#本质论第二章。
基本数据类型
C#的基本数据类型包括整型,浮点类型以及decimal
的特殊浮点类型。
整数类型
- C#的所有基本类型都有短名称和完整名称,完整名称对应于基类库(Base Class Library)中的类型命名。
- C#的整数类型共有8种:
sbyte
byte
short
ushort
int
uint
long
ulong
,其中对应的数据类型所占的大小分别为8位
16位
32位
64位
。对应的范围为2的相应次方个数,具体表示为负2的n-1次方
到2的n-1次方
。
浮点类型
- 二进制浮点类型无法精确的表示某个数,除非用分数表示时,其分母为2的整数次幂。
- C#的浮点类型有两种:
float
double
,对应的数据类型为32位
与64位
。
//TODO 具体的表示范围原理待考。
- 十进制浮点类型:C#提供了128位精度的十进制浮点类型
decimal
,适合大而精确的计算,它保证范围内的所有十进制数都是精确的。
字面量(literal value)
就是字面值,一种常量,编译器会自动的将其转换成基本数据类型。另外C#编译器允许向非int数值类型赋值,前提是其值对于目标数据类型是合法的,但这只对字面量成立。
- 解析顺序:解析成能够存储该值的第一种数据类型。
- 没有后缀的数值字面量:int
uint
long
ulong
- 具有后缀U的数值字面量: uint
ulong
- 具有后缀L的数值字面量: long
ulong
- 具有LU或UL后缀的数值字面量: ulong
布尔类型以及字符类型
- 布尔类型:条件类型,大小为一个字节。
- 字符类型:
char
表示16位字符,取值范围与ushort
相同,但是char
是一种独特类型。
字符串
零或多个字符组成的有限序列称为字符串。
- 在字符串前面使用
@
可以指明转义序列不被处理,结果是一个逐字字符串字面量(verbatim string literal),不仅将反斜杠当做普通字符处理,还会逐字解释空白字符。 - 字符串插值:在一个字符串字面量前加上一个
$
符号前缀,然后将表达式嵌入大括号中,这样做用于支持插入表达式。
System.Console.WriteLine($"Your full name is {firstname} {lastname}")
事实上这样写调用了string.Format()
。 using
与using static
指令: 静态方法的调用通常为:命名空间前缀+类型名,通过using static
+命名空间前缀+类型名来避免重复显式声明命名空间前缀+类型名。但其只对静态方法和属性有效。
关键字:null
与void
null
值只能赋给引用类型,指针类型与可空值类型。- 赋值为
null
的变量已被设置,使其不指向任何位置,而未赋值的变量未被设置,此两者不能等同。 void
:
- 标记方法不返回任何数据
- 表示指针指向未知类型的存储位置。
隐式类型的局部变量:var
只要在声明变量的同时用确定类型的表达式初始化它,就可以不必显式的指定数据类型。
虽然允许使用var
取代显式的数据类型,但是在数据类型已知的情况下,最好不要使用var
,这是出于可读性以及正确性的考虑,除非右侧的数据类型十分明显,否则应避免使用var
类型。
- 匿名类型:匿名类型是在方法内部动态声明的数据类型,而不是显式的类定义来声明的。
- 通过
var
,可以将匿名类型的实例赋给隐式类型的局部变量:以获得更少数据元素的功能联合使用。
var patent1 =
new { Title = "bifocals",
YearOfPublication = "1784" };
类型分类
所有类型都可以归为值类型或引用类型,它们的区别在于复制方式:值类型的数据总是进行值复制,引用类型的数据总是进行引用复制。
值类型
值类型变量直接包含值,变量引用的位置就是值在内存中实际存储的位置,
将第一个变量的值赋给第二个变量将在新变量的位置创建一个原始变量的值的一个内存副本,改动任何一个变量的值都不会影响另一个。
将值类型的实例传递给方法,也会生成一个副本,对参数的任何修改不会影响到原始值。
引用类
引用类型的值存储的是对数据存储位置的引用,而不是直接存储数据,运行时要先从变量中读取内存位置,再跳转到包含数据的内存位置。(类似于指针?)
引用类型指向的内存区域称之为“堆”。
引用类型不像值类型那样要求创建数据的内存副本,所以复制引用类型的实例比复制打的值类型实例更高效。
由于引用类型只复制对数据的引用,所以两个不同的变量可运用相同的数据,同时,通过修改其中一个变量来更改对象的字段,其他变量也会改变。
可空修饰符
根据定义,值类型不能包含引用,即使是对“无”的引用。为了声明可以存储null
的变量,我们使用可空修饰符:
int? count = null;
do{
// ...
}
while(count == null)
数据类型转换
显式转型:
在圆括号内指定希望变量转换成的类型。
在转换的过程中,数值有可能会溢出,这时可以将代码块放入checked
块中,会使运行时引发System.OverflowException
异常。
unchecked
作用与之相反,强制不进行溢出检查。
隐式转型:不发生精度的丢失时,可隐式的发生类型转换。
不使用转型操作符的转换
- 字符串类型->数值类型:
Parse()
- 数值类型->字符串类型:
ToString()
TryParse()
转换失败时不引发异常,而是返回false
。