《C#编程入门与应用》—3.4 数据类型转换
3.4 数据类型转换
由于C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或者无法用于 存储其他类型的值,除非该类型可以转换为变量的类型。但是,有时候可能需要将值复制到 其他类型的变量或方法参数中。
例如,现在有一个整数变量,需要将该变量作为参数类型化为 double,或者可能需要将 类变量赋给接口类型的变量,这些类型的操作称为数据类型转换。数据类型的转换是在所赋 值的数值类型与被变量接受的数据类型不一致时发生的,它需要从一种数据类型转换成另一种数据类型。在 C# 中,数据类型的转换可以分为隐式转换 ( 自动类型转换 ) 和显式转换 ( 强 制类型转换 ) 两种。
3.4.1 隐式转换
隐式转换就是系统默认的、不需要加以 声明就可以进行的转换。在隐式转换过程中, 编译器无须对转换进行详细检查就能够执行 转换。隐式转换是一种安全类型的转换,不 会导致数据丢失,因此不需要任何特殊的语 法。简单地说,从较小整数类型到较大整数 类型的转换以及从派生类到基类的转换都是 隐式转换。
C# 中经常说的装箱转换实际上就是一种 隐式类型转换。下面介绍隐式数值转换、隐 式枚举转换和隐式引用转换。
1.隐式数值转换
顾名思义,隐式数值转换就是基本数据 类型之间的转换,它实际上就是从低精度的 数值类型到高精度的数值类型的转换。隐式 数值转换包含以下几种:
● 从sbyte 类型到 short、int、long、float、 double 或decimal 类型。
● 从byte类型到short、ushort、int、uint、 long、ulong、float、double 或 decimal 类型。
● 从 short 类型到int、long、float、double 或decimal 类型。
● 从ushort 类型到int、uint、long、ulong、 float、double 或 decimal 类型。
● 从 int 类型到long、float、double 或者 decimal 类型。
● 从uint 类型到long、ulong、float、double 或 decimal 类型。
● 从 long 类型到float、double 或 decimal 类型。
● 从 ulong 类型到float、double 或 decimal 类型。
● 从 char 类型到ushort、int、uint、long、 ulong、float、double 或decimal 类型。
● 从 float 类型到 double 类型。
其中,从 int、uint 或 long 到 float 以及 从long到double的转换可能会导致精度下降, 但是绝不会引起数量上的丢失,其他的隐式 数值转换则不会。同时,再次强调,不存在 到 char 类型的隐式转换,这意味着其他整型 值不能自动转换为char 类型,这一点必须 注意。
【例3-19】
创建控制台应用程序,在 Main() 方法 中分别声明byte、ushort 和 float 类型的变量 num1、num2 和 num3,并为变量赋值,最后 输出。代码如下:
在上述代码中,首先声明byte 类型的 num1 变量,将值指定为16,并且将该变 量的值传递给num2,num2 是一个ushort 类型,这是一个隐式转换。然后重新指 定 num2 变量的值, 将值传递给num3 变 量,该变量是float 类型的,这同样是隐式 转换。
编译并执行上述代码,最终结果如下:
num1=16
num2=16
num2=65535
num3=65535
如果在上面的程序语句之后再加上一句:
num2 = num2 + 1;
在重新编译程序时,编译器会直接给出 一条错误信息:
无法将类型"int" 隐式转换为"ushort"。存在 一个显式转换 ( 是否缺少强制转换 ?)
这说明,从整数类型65536 到无符号短 类型 num2 并不存在隐式转换。
2.隐式枚举转换
隐式枚举转换允许把十进制整数0 转换 成任何枚举类型,对应其他的整数则不存在 这种隐式转换。
【例3-20】
创建控制台应用程序,首先通过enum 声明枚举类型的Weekday,该枚举类型中包 含 7 个值。接着在Program 类的Main() 方法 中声明Weekday 类型的局部变量day,并将 0 赋予该变量,最后将day 变量的值输出。 代码如下:
编译执行上述代码,最终输出的结果是:
Sunday
如果把程序中的day=0 修改为day=1 或 其他的整数值,程序在编译时会报错:
无法将类型"int" 隐式转换为"ChapterThree. Weekday"。存在一个显式转换(是否缺少强制转换?)
3.隐式引用转换
隐式引用转换是指一类引用类型之间的转 换,这种转换总是可以成功,因此不需要在运 行时进行任何检查。引用转换无论是隐式还是 显式的,都不会更改所转换的对象的引用标识。 换句话说,虽然引用转换可以改变该引用的类 型,但是不会更改所引用对象的类型或值。
隐式引用转换包含以下几类:
● 从任何引用类型到对象类型object 的 转换。
● 从任何类类型S 到任何类类型T 的转 换,其中 S 是 T 的派生类。
● 从任何类类型S 到任何接口类型T 的 转换,其中 S 实现了接口 T。
● 从任何接口类型S到任何接口类型T, 其中 T 是 S 的父接口。
● 从元素类型为SE 的数组类型S 到元素 类型为 TE 的数组类型 T 地转换,这种 转换需要满足下列条件:
◆ S 和 T 只是元素类型不同,但是S 和 T 具有相同的维数。
◆ SE 和 TE 都是引用类型。 ◆ 存在从SE到TE的隐式引用转换。
◆ 从任何数组类型到 System.Array 的 转换。
◆ 任何委托类型到System.Delegate 的转换。
◆ 从任何类型到System.ICLoneable 的转换。
◆ 从空类型(null) 到任何引用类型的 转换。
【例3-21】
创建控制台应用程序,分别创建School 和 JianXinSchool 类,JianXinSchool 类继承 School 类。在 Main() 方法中分别实例化这两 个类,实例对象的名称分别是 father 和 son, 将 son 的值赋给 father。代码如下:
该例符合隐式类型转换,从JianXinSchool 转换到School,且 JianXinSchool 类是School 类的派生类。 又如,下面的几行代码是无法通过程序 编译的,因为数组的元素类型是值类型,C# 中不存在这样的隐式转换:
- 点赞
- 收藏
- 关注作者
评论(0)