扩大转换和收缩转换 (Visual Basic)
类型转换的一个重要注意事项是,转换的结果是否在目标数据类型的范围内。
扩大转换将值更改为数据类型,后者可允许原始数据的任何可能值。 扩大转换会保留源值,但可更改其表示形式。 如果从整型类型转换为 Decimal
,或者从 Char
转换为 String
,则会发生这种情况。
“收缩转换” 将值更改为可能无法保存某些可能值的数据类型。 例如,将小数值转换为整型类型时,将对其进行舍入,并且将转换为 Boolean
的数值类型简化为 True
或 False
。
扩大转换
下表显示了标准扩大转换。
数据类型 | 扩大到数据类型 1 |
---|---|
SByte | SByte , Short , Integer , Long , Decimal , Single , Double |
Byte | Byte , Short , UShort , Integer , UInteger , Long , ULong , Decimal , Single , Double |
Short | Short , Integer , Long , Decimal , Single , Double |
UShort | UShort , Integer , UInteger , Long , ULong , Decimal , Single , Double |
整数 | Integer 、Long 、Decimal 、Single 、Double 2 |
UInteger | UInteger 、Long 、ULong 、Decimal 、Single 、Double 2 |
Long | Long 、Decimal 、Single 、Double 2 |
ULong | ULong 、Decimal 、Single 、Double 2 |
十进制 | Decimal 、Single 、Double 2 |
Single | Single ,Double |
双精度 | Double |
任何枚举类型 (Enum) | 它的基础整型类型,以及基础类型扩大到的任何类型。 |
Char | Char ,String |
Char 数组 |
Char 数组、String |
任何类型 | Object |
任何派生类型 | 从中派生出它的任何基类型3。 |
任何类型 | 它实现的任何接口。 |
无 | 任何数据类型或对象类型。 |
1 根据定义,每个数据类型都会扩大到其自身。
2 如果从 Integer
、UInteger
、Long
、ULong
或 Decimal
转换为 Single
或 Double
,可能会导致丢失精确度,但绝不会导致丢失大小。 从这个意义上说,它们不会导致信息丢失。
3 从派生类型到其某个基类型的转换都是扩大转换,这可能令人惊讶。 理由是,派生类型包含基类型的所有成员,因此它被限定为基类型的实例。 反过来,基类型不包含由派生类型定义的任何新成员。
扩大转换在运行时总是会成功,绝不会导致数据丢失。 无论 Option Strict 语句是否将类型检查开关设置为 On
或 Off
,都始终可隐式执行它们。
收缩转换
标准收缩转换包括:
上表中的扩大转换的反向方向(每个类型扩大到其自身的情况除外)
Boolean 类型和任何数值类型之间的任意方向转换
从任何数值类型到任何枚举类型 (
Enum
) 的转换从数据类型/对象类型到派生自其自身的类型的转换
收缩转换在运行时并非总会成功,可能会失败或导致数据丢失。 如果目标数据类型无法接收正在转换的值,则会发生错误。 例如,数字转换可能会导致溢出。 编译器不允许隐式执行收缩转换,除非 Option Strict 语句将类型检查开关设置为 Off
。
注意
对于从 For Each…Next
集合中的元素到循环控制变量的转换,将抑制收缩转换错误。 有关详细信息和示例,请参阅关于 Each...Next 语句的“收缩转换”一节。
何时使用收缩转换
如果知道源值可转换为目标数据类型,而不会出错或丢失数据,则可使用收缩转换。 例如,如果你有一个 String
,你知道它包含“True”或“False”,那么你可使用 CBool
关键字来将它转换为 Boolean
。
转换过程中的异常
扩大转换始终会成功,因此它们不会引发异常。 收缩转换在失败时,最常见的是引发以下异常:
InvalidCastException - 如果在两个类型之间未定义转换
OverflowException -(仅限整型类型)如果转换后的值对于目标类型来说太大
如果某个类或结构定义一个 CType 函数,该函数充当与该类或结构之间的转换运算符,那么 CType
可能会引发它认为合适的任何异常。 此外,该 CType
可能会调用 Visual Basic 函数或 .NET Framework 方法,进而可能引发各种异常。
引用类型转换期间的更改
从引用类型进行转换只复制指向值的指针。 值本身不以任何方式进行复制或更改。 唯一可更改的是保存指针的变量的数据类型。 在下面的示例中,数据类型从派生类转换为其基类,但这两个变量现在指向的对象保持不变。
' Assume class cSquare inherits from class cShape.
Dim shape As cShape
Dim square As cSquare = New cSquare
' The following statement performs a widening
' conversion from a derived class to its base class.
shape = square