2.C#的显式类型转换
显式类型转换,又叫强制类型转换。与隐式转换正好相反,显式转换需要用户明确地指定转换的类型。比如下面的例子把一个类型显式转换为
类型:
long l=5000;
int i=(int)l;
拆箱转换就是一种显式转换。这里我们还将讲解以下转换的规则:
●显式数值转换
●显式枚举转换
●显式引用转换
显式转换可以发生在表达式的计算过程中。它并不是总能成功,而且常常可能引起信息丢失。
显式转换包括所有的隐式转换,也就是说把任何系统允许的隐式转换写成显式转换的形式都是允许的,如:
int i=10;
long l=(long)i;
2.1 显式数值转换
显式数值转换是指当不存在相应的隐式转换时,从一种数字类型到另一种数字类型的转换。包括:
●从sbyte到byte,ushort,uint,ulong,或char。
●从byte到sbyte或char。
●从short到sbyte,byte,ushort,uint,ulong,或char。
●从ushort到sbyte,byte,short,或char。
●从int到sbyte,byte,short,ushort,uint,ulong,或char。
●从uint到sbyte,byte,short,ushort,int,或char。
●从long到sbyte,byte,short,ushort,int,uint,ulong,或char。
●从ulong到sbyte,byte,short,ushort,int,uint,long,或char。
●从char到sbyte,byte,或short。
●从float到sbyte,byte,short,ushort,int,uint,long,ulong,char,或decimal。
●从double到sbyte,byte,short,ushort,int,uint,long,ulong,char,float,或decimal。
●从decimal到sbyte,byte,short,ushort,int,uint,long,ulong,char,float,或double。
这种类型转换有可能丢失信息或导致异常抛出,转换按照下列规则进行:
●对于从一种整型到另一种整型的转换,编译器将针对转换进行溢出检测,如果没有发生溢出,转换成功,否则抛出一个OverflowException异
常。这种检测还与编译器中是否设定了checked选项有关。
●对于从float,double,或decimal到整型的转换,源变量的值通过舍入到最接近的整型值作为转换的结果。如果这个整型值超出了目标类型的
值域,则将抛出一个OverflowException异常。
●对于从double到float的转换,double值通过舍入取最接近的float值。如果这个值太小,结果将变成正0或负0;如果这个值太大,将变成正
无穷或负无穷。如果原double值是Nan,则转换结果也是NaN。
●对于从float或double到decimal的转换,源值将转换成小数形式并通过舍入取到小数点后28位(如果有必要的话)。如果源值太小,则结果
为0;如果太大以致不能用小数表示,或是无穷和NaN,则将抛出InvalidCastException异常。
●对于从decimal到float或double的转换,小数的值通过舍入取最接近的值。这种转换可能会丢失精度,但不会引起异常。
程序清单2-1:
using system;
class Test
{
static void Main(){
long longValue=Int64.MaxValue;
int intValue=(int)longValue;
Console.WriteLine("(int){0}={1}",longValue,intValue);
}
}
这个例子把一个int类型转换成为long类型,输出结果是:
(int)9223372036854775807=-1
这是因为发生了溢出,从而在显式类型转换时导致了信息丢失。
2.2 显式枚举转换
显式枚举转换包括以下内容:
●从sbye,byte,short,ushort,int,uint,long,ulong,char,float,double,或decimal到任何枚举类型。
●从任何枚举类型到sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,或decimal。
●从任何枚举类型到任何其它枚举类型。
显式枚举转换是这样进行的:它实际上是枚举类型的元素类型与相应类型之间的隐式或显式转换。比如,有一个元素类型为int的枚举类型E,
则当执行从E到byte的显式枚举转换时,实际上作的是从int到byte的显式数字转换;当执行从byte到E的显式枚举转换时,实际上是执行byte到
int的隐式数字转换。
比如,对程序1-2,我们改写如下:
程序清单2-2:
using System;
enum Weekday{
Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
};
class Test
{
public static void Main(){
Weekday day;
day=(Weekday)3;
Console.WriteLine(day);
}
}
程序的输出是:
3
2.3 显式引用转换
显式引用转换包括:
●从对象到任何引用类型
●从类类型S到类类型T,其中S是T的基类。
●从基类型S到接口类型T,其中S不是密封类,而且没有实现T。
●从接口类型S到类类型T,其中T不是密封类,而且没有实现S。
●从接口类型S到接口类型T,其中S不是T的子接口。
从元素类型为Ts的数组类型S到元素类型为Tt的数组类型T的转换,这种转换需要满足下列条件:
●S和T只有元素的数据类型不同,而维数相同。
●Ts和Tt都是引用类型。
●存在从Ts到Tt的显式引用转换。
●从System.Array到数组类型。
●从System.Delegate到代表类型。
●从System.ICloneable到数组类型或代表类型。
显式引用转换发生在引用类型之间,需要在运行时检测以确保正确。
为了确保显式引用转换的正常执行,要求源变量的值必须是null或者它所引用的对象的类型可以被隐式引用转换为目标类型。否则显式引用转
换失败,将抛出一个InvalidCastException异常。
不论隐式还是显式引用转换,虽然可能会改变引用值的类型,却不会改变值本身。
|