第二章 控制语句
刚开始的时候,我们并不太能体会控制语句的重要性?我们为什么需要控制语句呢?我们知道,程序的执行都是一行接一行、自上而下地进行,不遗漏任何代码。如果所有的应用程序都这样执行,那我们能做的工作就很有限了。如果我们需要进行有条件的执行或是循环的执行相同的代码又该怎么办呢?显然自上而下地进行执行代码满足不了需求;这时,我们就需要流程控制语句了,让代码有选择性的执行或者循环。
本章我们重点向大家介绍控制语句的相关知识,希望对大家有所帮助。
本章的学习重点:
◆ 隐式转换
◆ 显示转换
2.2类型转换
C#中的类型转换有两种分类方法,一种是根据转换方式的不同进行划分,可以分为显式 (Explicit) 转换和隐式 (Implicit) 转换两种;另外一种是根据源类型和目标类型之间的关系进行划分,可以分为变换 (Conversion)、投射 (Cast)和装箱/拆箱 (Boxing/Unboxing)。本文将向大家详细介绍显式转换和隐式转换的相关知识。
类型转换发生在什么时候——当发生值的复制时,可能会发生类型转换。所谓“值的复制”,包括赋值运算和方法传参。如果被赋值的变量或方法的形式参数的类型与实际的对象类型不同,就需要进行类型转换。
2.2.1隐式转换
隐式转换是指将低精度数值转换为高精度数值,可以直接赋值而不用手动添加其他代码。隐式转换可能在多种情形下发生,包括在调用方法时或在赋值语句中。例如:
int intValue = 10;
double doubleValue = intValue;
从int类型转换到double类型就是一种隐式转换。隐式转换一般不会失败,转换过程中也不会导致信息丢失。隐式转换就是系统默认的、不需要加以声明就可以进行的转换。在隐式转换过程中,编译器无需对转换进行详细检查就能够安全地执行转换。
隐式转换:一般是低类型向高类型转化,能够保证值不发生变化。
下面我们列出了隐式数值的转换规则:
从 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。
当然,没必要记住它们,因为很容易看出编译器可以执行哪些隐式转换。之前的一个表列出了每种简单数字类型的取值范围。这些类型的隐式转换规则是:任何类型A,只要其取值范围完全包含在类型B的取值范围内,就可以隐式转换为类型B。
原因很简单,如果要把一个值放在变量中,而该值超出了变量的取值范围,就会出问题。例如,short类型的变量可以存储0~32677的数字,而byte可以存储的最大值是255,所以如果要把一个short值转换为byte值就会出问题。如果short包含的值在256~32767之间,该数值就不能放在byte中。
但是,如果short类型变量中的值小于255,就能转换这个值,对吗?答案是可以,但必须使用显示转换,执行显示转换有点类似于“我已经知道你对我这么做提出了警告,但我将对其后果负责”。显示转换我们将在下一节详细介绍。
这里还有几点需要注意的:
1、不存在向 char 类型的隐式转换,因此其它整型的值不会自动转换为 char 类型。
2、浮点型不能隐式地转化为decimal型。
2.2.2显示转换
显式类型转换,又叫强制类型转换。与隐式转换正好相反,是指当不存在相应的隐式转换时,从一种数字类型到另一种数字类型的转换。显式转换需要用户明确地指定转换的类型,而且不能保证数据的正确性。
其声明语法如下:
(type)(表达式)
例如:下面的例子把一个long类型显式转换为int类型:
long longValue = 5000;
int intValue = (int)longValue;
显式转换可以发生在表达式的计算过程中。它并不是总能成功,而且常常可能引起信息丢失。
显式转换包括所有的隐式转换,也就是说把任何系统允许的隐式转换写成显式转换的形式都是允许的,例如:
int intValue = 10;
long longValue = (long)intValue;
下面我们列出了显式数值的转换规则:
从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。
这种类型转换有可能丢失信息或导致异常抛出,转换按照下列规则进行:
1、对于从一种整型到另一种整型的转换,编译器将针对转换进行溢出检测,如果没有发生溢出,转换成功,否则抛出一个OverflowException异常。这种检测还与编译器中是否设定了checked选项有关。
2、对于从float,double或decimal到整型的转换,源变量的值通过舍入到最接近的整型值作为转换的结果。如果这个整型值超出了目标类型的值域,则将抛出一个OverflowException异常。
3、对于从double到float的转换,double值通过舍入取最接近的float值。如果这个值太小,结果将变成0。如果原double值是NaN,则转换结果也是NaN。
4、对于从float或double到decimal的转换,源值将转换成小数形式并通过舍入取到小数点后28位(如果有必要的话)。如果源值太小,则结果为0;如果太大以致不能用小数表示,或是无穷和NaN,则将抛出InvalidCastException异常。
5、对于从decimal到float或double的转换,小数的值通过舍入取最接近的值。这种转换可能会丢失精度,但不会引起异常。