在高级语言中数据类型是一个很重要的概念,只具有相同的数据类型的对象才能够互相操作。很多的时候为了不同类型数据的运算(如整型和浮点型的运算等),需要把数据从一 种类型转换为另一种类型,即进行类型转换
一. 隐式转换
隐式转换就是系统默认的,无需指明的转换。进行隐式转换时,编译器不需要进行检查就能自动将操作数转换为相同的类型。隐式转换只允许发生在从值范围较小的数据类型到值范围较大的数据类型的转换,转换都的数值大小不受影响。这是因为值范围较大的数据具有足够的空间存放值范围较小的数据
int i =1; //声明一个int类型变量并初始化 long result =i; //int类型隐式转换为long类型
TIPS: 从int,uint,long,ulong到float,以及重long,ulong到double的转换可能导致精度损失,但不会影响它的数量级。
二. 显示转换
显示类型转换,又称强制类型转换,它需要在代码中明确地声明要转换的类型。当需要把值范围较大的数据类型转换为值范围较小的数据类型时,不能使用隐式类型,而必须使用显示类型。当然,所有的隐式转换也都可以采用显示转化来表示
下面代码进行不同数据类型转换的显示转换:
int i = 1; //声明一个int类型变量并初始化long result =(long)i; //int类型显示转换为long类型double m = 1.2; //声明一个double类型变量并初始化int n=(int)m; //double类型显示转换为int类型
显示转换在把值范围较大的数据类型转换为值范围较小的数据类型时,可能会导致溢出错误。
double m = 22222222222.2; int n = (int)m;
上述语句中,double类型变量m的值比int类型的最大值还要大,发生了溢出错误。因此在进行显示类型转换时,通常使用checked运算符来检查转换是否安全,如上述语句可以改写为:
double m = 22222222222.2; int n = checked((int)m);
这时在执行上述语句,系统会抛出一个异常,提示“算数运算导致溢出”。
三. 装箱和拆箱
装箱和拆箱允许值类型变量和引用类型变量项目转换。装箱是将值类型转换为引用类型,拆箱是将引用类型转换为值类型。
1. 对值类型进行装箱转换时,会在内存堆中分配一个对象实例,并将该值赋值到该对象中。
2. 对引用类型进行拆箱转换时,需要使用强制操作符,将存放在堆中的引用类型的值复制到栈中形成值类型。
(1)检查引用类型变量,确认它是否包装了值类型的数。
(2)把引用类型变量的值复制到值类型的变量中。
TIPS:在执行拆箱转换时,要遵循类型一致的原则。比如,将一个int类型变量进行了装箱转换,那么在对其进行拆箱转换时,一定也要拆箱为int类型变量,否则会出现异常。
四. Convert类
Convert类用于将一个基本数据类型转换为另一个基本数据类型,返回与指定类型的值等效的类型。受支持的基类型有Boolean,Char,SByte,Byte,Int16,Int32,Int64,UInt16,UInt32,UIn64,Single,Double,Decimal,DateTime和String。可根据不同的需要使用Convert类的公共方法实现不同数据类型的转换。Convert类所执行的实际转换操作分为以下3类;
* 从某类型到它本身的转换只返回该类型,不实际执行任何操作。
* 无法产生有意义的结果的转换引发InvaildCastException,不实际执行任何转换。下列转换会引发异常:从Char类型于Boolean,Single,Double,Decimal,DateTime类型之间的转换,以及DateTime类型与除String之外的任何类型之间的转换。
* 某种基类型与其他基类型的相互转换(引发InvaildCastException除外)。
Convert类的所有方法,都是静态的,因此可以直接调用。Convert类中方法的形式都为ToXXX(XXX),即实现把参数XXX转换为XXX类型。