3.6 数据类型转换
类型转换是将一个值从一种数据类型更改为另一种数据类型的过程。例如,可以将string 类型的数据 “457” 转换为int 类型,而且可以将任意类型的数据转换为string 类型。
数据类型转换有两种方式,即隐式类型转换与显式类型转换。如果从低精度数据类型向高精度数据类型转换,则永远不会溢出,并且总是成功的;而从高精度数据类型向低精度数据类型转换,则必然会有信息丢失,甚至有可能失败。这种转换规则就像图3.30 所示的两个场景,高精度数据类型相当于一个大水杯,低精度数据类型相当于一个小水杯,大水杯可以轻松装下小水杯中所有的水,但小水杯却无法装下大水杯中所有的水,装不下的部分必然会溢出。

图3.30 用大、小水杯类比数据类型转换的示意图
3.6.1 隐式类型转换

隐式类型转换是不需要声明就能进行的转换,在进行隐式类型转换时,编译器不需要进行检查就能自动进行转换。下列基本数据类型会涉及数据转换(不包括逻辑类型),这些类型按精度从 “低” 到 “高” 排列的顺序为byte < short < int < long < float < double,可对照图3.31,其中char 类型比较特殊,它可以与部分int 类型数字兼容且不会发生精度变化。

图3.31 自动转换的兼容顺序图
例如,将int 类型的值隐式转换成long 类型,代码如下。

3.6.2 显式类型转换

有很多场合不能进行隐式类型转换,否则编译器会出现错误。例如,下面的类型在进行隐式类型转换时会出现错误。
●int 类型转换为short 类型:会丢失数据。
●int 类型转换为uint 类型:会丢失数据。
●float 类型转换为int 类型:会丢失小数点后面的所有数据。
●double 类型转换为int 类型:会丢失小数点后面的所有数据。
●数值类型转换为char 类型:会丢失数据。
●decimal 类型转换为其他数值类型:decimal 类型的内部结构不同于整数和浮点数。
如果遇到上面类型之间的转换,就需要用到C# 中的显式类型转换。显式类型转换也称为强制类型转换,它需要在代码中明确地声明要转换的类型。如果要把高精度的变量转换为低精度的变量,就需要使用显式类型转换。
显式类型转换的一般形式为:
( 类型说明符) 表达式
其功能是把表达式的运算结果强制转换为类型说明符所表示的类型。
例如,下面的代码用来把x 转换为float 类型。

通过显式类型转换,可以解决高精度数据向低精度数据转换的问题。例如,将double类型的值4.5 赋给int 类型的变量时,可以使用下面的代码。

3.6.3 使用Convert 类进行转换

在3.6.2 节中讲解了使用 “( 类型说明符) 表达式” 可以进行显式类型转换,下面使用这种方式实现如下类型转换。

按照代码的本意,i 的值应该是3000000000,但在运行上面两行代码时,发现i 的值是-1294967296。这主要是由于int 类型的最大值为2147483647,而3000000000 比2147483647 大,所以在使用上面的代码进行显式类型转换时出现了与预期不符的结果,但是程序并没有报告错误。如果在实际开发中遇到这种情况,则可能会引起大的Bug。那么,在遇到这种类型的错误时,有没有一种方式能够向开发人员报告错误呢?答案是“有”。C# 中提供了Convert 类,该类也可以进行显式类型转换,它的主要作用是将一个基本数据类型转换为另一个基本数据类型。Convert 类的常用方法及说明如表3.10 所示。
表3.10 Convert 类的常用方法及说明

续表

例如,定义一个double 类型的变量x,并赋值为198.99,使用Convert 类将其显式转换为int 类型,代码如下。

下面使用Convert 类的ToInt32 方法对本小节开始的两行代码进行修改,修改后的代码如下。

再次运行这两行代码,则会出现如图3.32 所示的错误提示信息。

图3.32 再次运行代码时出现的错误提示信息
这样,开发人员即可根据如图3.32 所示的错误提示信息对程序代码进行修改,避免程序出现逻辑错误。