FCL类型
使用以下语法分配一个整数
System.Int32 a=new System.Int32();
这种语法较为繁琐,C#允许换用如下所示的语法
int a=0;
这种语法不仅增强了代码可读性,生成的IL代码还与使用System.Int32生成的IL代码完全一致。编译器直接支持的数据类型称为基元类型(primitive type)。基元类型直接映射到Framework类库(FCL)中存在的类型。例如C#的int直接映射到System.Int32类型。
从另一个角度,可以认为C#编译器自动假定所有源代码文件都添加了以下using指令
using byte=System.Byte using int=System.Int32 ...
C#语言规范称:“从风格上说,最好是使用关键字,而不是使用完整的系统类型名称。”
作者不同意,作者认为使用关键字混淆了诸如Int64/Int32,String/string,C#将long映射到System.Int63,C++却将long视为Int32等等。
考虑到这些原因,CLR via C#这本书坚持使用FLC类型名称。
由第四章的类型转换的讨论,可能会认为如下代码无法编译。毕竟System.Int32和System.Int64是不同的类型,相互不存在派生关系。但是事实上编译和运行都没问题。因为C#编译器非常熟虚基元类型,会在编译代码时应用自己的特殊规则。具体的说只有在转换安全的时候,C#才允许隐式转换。所谓安全是指不会发生数据丢失,比如Int32转换到Int64.
Int32 i=5;//32位值 Int64 l=i;//隐式转型为64位
除了转型,基本类型还能写成字面值(literal)。字面值可悲看成是类型本身的实例,所以可以像下面为实例调用实例方法。
Console.WriteLine(123.ToString()+456.ToString());//"123456"
checked和unchecked基元类型操作
对基元类型执行的许多算术运算都可能造成溢出
Byte b=100; b=(Byte)(b+200);//b现在包含44(或者十六进制2C)
溢出大多时候是我们不希望的。如果没有检测到这种一出,会导致应用程序行为失常。但极少数时候,如计算哈希值或者校验和,这种溢出不仅可以接受,还是我们希望的。
让C#编译器控制溢出的一个办法是使用/checked编译器开关。该开关指示编译器在生成代码时,使用加减乘鸡和转换指令的溢出检查版本。这样生成的代码在执行时会稍慢些,因为CLR会检查这些运算,判断是否发生一出。如果溢出,CLR抛出OverflowException异常
除了全局性地打开或关闭溢出检查,还可以通过checked和unchecked操作符来提供这种灵活性。
//使用unchecked操作符 UInt32 invalid=unchecked((UInt32)(-1));//OK //使用checked操作符 Byte b=100; b=checked((Byte)(b+200));//抛出OverflowException异常
出了两种操作符,C#还支持checked和unchecked语句,他们造成一个块中的所有表达式都进行或不进行溢出检查。事实上,如果使用了checked语句,就可将+=操作符用于Byte,稍微简化一下代码。
checked { Byte b=100; b+=200;//该表达式会进行溢出检查 }
重要提示:由于checked操作符和语句唯一的作用就是决定生成哪个版本的加减乘和数据转换IL指令,所以在checked操作符或语句中调用方法,不会对该方法造成任何影响,如下例所示。
checked { //假定SomeMethod试图把400加载到一个Byte中 SomeMethod(400); //SomeMethod可能会,也可能不会抛出异常 //但如果其使用checked指令编译,就可能会抛出异常 //但这和当前的checked语句无关 }
作者对程序员有以下建议:
CLR via C#学习笔记-第五章-基元类型、引用类型和值类型-编程语言的基元类型
原文:https://www.cnblogs.com/errornull/p/9743295.html