目录
16.1 什么是转换
16.2 隐式转换
16.3 显示转换和强制转换
强制转换
16.4 转换的类型
16.5 数字的转换
16.5.1 隐式数字转换
16.5.2 溢出检测上下文
1、checked和unchecked运算符;
2、checked语句和unchecked语句
16.5.3 显示数字转换
1.整数类型到整数类型
2.float或double转到整数类型
3.decimal到整形类型
4.double到float
5.float或double到decimal
6.decmal 到float或double
16.6 引用转换
16.6.1 隐式引用转换
16.6.2 显示引用转换
16.6.3 有效显示引用转换
16.7 装箱转换
16.7.1 装箱是创建副本
16.7.2 装箱转换
16.8 拆箱转换
拆箱转换
16.9 用户自定义转换
16.9.1 用户自定义转换的约束
16.10 is运算符
16.11 as运算符
声明两个不同类型的变量,然后把一个变量(源)的值赋值给另一个变量(目标)的过程就发生了类型转换。
有些类型的转换不会丢失数据或精度,例如将8位的值转换为16位是非常容易的,而且不回丢失数据
如果把短类型转换为长类型,对于长类型来说,保存所有短类型的字符很简单。然而在其他情况下,目标类型也许无法在不损失数据的情况下提供源值。
对于预定义的类型,C#会自动将一个数据类型转换为另一个数据类型,但只是针对那些从源类型到目标类型不会发生数据丢失的情况。也就是说,对于源类型的任意值再被转换为目标类型时会丢失的情况,语言是不会提供这两种类型的自动转换的。如果希望对这样的类型转换就必须使用显式转换,强制类型转换表达式;
我们使用强制转换表达式的时候,就意味着要承担执行操作可能会引起丢失数据的情况,
有很多标准的。预定义的用于数字和引用类型的转换
任何数字类型都可以转换为其他数字类型,一些转换是隐式的,而另外一些转换则必须是显式地
显示转换可能会失去数据并且不能在目标类型同等的表示源值。对于整数类型,C#给我们提供了选择运行时是否应该进行类型转换时检测结果溢出的能力。这将通过checked运算符和checked语句来实现。
checked和unchecked运算符控制表达式的溢出检测上下文。表达式放置在一对圆括号内并且不能是一个方法。语法如下所示:
checked和unchecked运算符用于圆括号内的单个表达式。而checked和unchecked语句执行相同的功能,但控制的是一块代码中的所有转换,而不是单个表达式。
checked语句和unchecked语句可以被嵌套在任意层次。
隐式转换不会丢失数据,但是显示转换会丢失数据:以下介绍各种显示数字转换:
在checked的情况下如果转换会丢失,操作就会抛出OverflowException异常。在unchecked情况下,丢失的位不会发出警告。
当把浮点类型转换为整数类型时,值会舍掉小数截断为最近的整数。
当从decimal转换到整数类型时,如果结果值不在目标类型额范围内,则CLR会抛出OverflowException
float类型的值占32位,而double类型的值占64位,double类型的值被舍入最接近的float类型的值
从decmal类型转换到float类型总会成功。但是会损失精度
引用类型对象由内存中的两部分组成:引用和数据;
委托可以隐式转换成图.NET BCL接口。Arrays数组,其中的元素是Ts类型可以隐式转换为
显示引用转换是从一个普通类型到一个更精确类型的引用转换。
显示转换包括:
如果转换的类型不受限制,很可能会导致我们很容易地尝试引用在实际并不存在的类成员。然而,编译器确实允许这样转换。到那时,如果系统在运行时遇到它们则会抛出一个异常,
在运行时能成功进行(也就是不抛出InvalidCastException异常)的显示转换有3种情况。
第一种语言已经为我们进行了隐式转换:
第二种:源引用是null:
第三种:由于源引用指向的实际数据可以被安全的进行隐式转换:
包括值类型在内的所有C#类型都派生自object。然儿1,值类型是高级轻量的类型,因为默认情况下在堆上不包括它们的对象组件。如果需要对象组件,我们可以使用装箱。装箱是一种隐式转换,它接受值值类型的值,根据这个值在堆上创建一个完整的引用类型对象并返回对象引用:
装箱返回的是值的引用类型副本。在装箱产生之后,该值有两份副本--原始值类型和引用类型副本,每一个都可以独立操作。
任何值类型ValueTypes都可以被隐式转换为object类型。System.Value或InferfaceT(如果ValueTypes实现了InterfaceT)。
拆箱(unboxing)是把装箱后的对象转换回值类型的过程。
拆箱是显示转换.
系统在把值拆箱成ValueTypeT时执行如下的步骤:
它检测到要拆箱的对象实际是ValueType的装箱值;
它把对象的值复制到变量:
尝试将一个值拆箱为非原始类型时就会抛出一个InvalidCastException异常。
除了标准转转,我们还可以为类和结构自定义 隐式和显示转换。
除了implicit和ecplicit关键字之外,隐式和显式转换的声明语法是一样的。
需要public和static修饰符。
有些转换是不会成功的,并且会在运行时抛出一个InvalidCastException异常。我们可以使用is运算符来检查转换是否会成功完成,从而避免盲目尝试转换。
is运算符的语法如下,Expr是源表达式:
as运算符和强制转换运算符类似,只是它不会抛出异常。如果转换失败,它返回的null而不是抛出异常。
需要注意的是as 和 is都只能用于引用转换和装箱转换。它们不能用于用户自定义转换或到值类型的转换