扩大转换和收缩转换 (Visual Basic)

类型转换的一个重要注意事项是,转换的结果是否在目标数据类型的范围内。

扩大转换将值更改为数据类型,后者可允许原始数据的任何可能值。 扩大转换会保留源值,但可更改其表示形式。 如果从整型类型转换为 Decimal,或者从 Char 转换为 String,则会发生这种情况。

“收缩转换” 将值更改为可能无法保存某些可能值的数据类型。 例如,将小数值转换为整型类型时,将对其进行舍入,并且将转换为 Boolean 的数值类型简化为 TrueFalse

扩大转换

下表显示了标准扩大转换。

数据类型 扩大到数据类型 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
整数 IntegerLongDecimalSingleDouble2
UInteger UIntegerLongULongDecimalSingleDouble2
Long LongDecimalSingleDouble2
ULong ULongDecimalSingleDouble2
十进制 DecimalSingleDouble2
Single SingleDouble
双精度 Double
任何枚举类型 (Enum) 它的基础整型类型,以及基础类型扩大到的任何类型。
Char CharString
Char 数组 Char 数组、String
任何类型 Object
任何派生类型 从中派生出它的任何基类型3
任何类型 它实现的任何接口。
任何数据类型或对象类型。

1 根据定义,每个数据类型都会扩大到其自身。

2 如果从 IntegerUIntegerLongULongDecimal 转换为 SingleDouble,可能会导致丢失精确度,但绝不会导致丢失大小。 从这个意义上说,它们不会导致信息丢失。

3 从派生类型到其某个基类型的转换都是扩大转换,这可能令人惊讶。 理由是,派生类型包含基类型的所有成员,因此它被限定为基类型的实例。 反过来,基类型不包含由派生类型定义的任何新成员。

扩大转换在运行时总是会成功,绝不会导致数据丢失。 无论 Option Strict 语句是否将类型检查开关设置为 OnOff,都始终可隐式执行它们。

收缩转换

标准收缩转换包括:

  • 上表中的扩大转换的反向方向(每个类型扩大到其自身的情况除外)

  • Boolean 类型和任何数值类型之间的任意方向转换

  • 从任何数值类型到任何枚举类型 (Enum) 的转换

  • String 类型与任何数值类型、BooleanDate 类型之间的任意方向转换

  • 从数据类型/对象类型到派生自其自身的类型的转换

收缩转换在运行时并非总会成功,可能会失败或导致数据丢失。 如果目标数据类型无法接收正在转换的值,则会发生错误。 例如,数字转换可能会导致溢出。 编译器不允许隐式执行收缩转换,除非 Option Strict 语句将类型检查开关设置为 Off

注意

对于从 For Each…Next 集合中的元素到循环控制变量的转换,将抑制收缩转换错误。 有关详细信息和示例,请参阅关于 Each...Next 语句的“收缩转换”一节。

何时使用收缩转换

如果知道源值可转换为目标数据类型,而不会出错或丢失数据,则可使用收缩转换。 例如,如果你有一个 String,你知道它包含“True”或“False”,那么你可使用 CBool 关键字来将它转换为 Boolean

转换过程中的异常

扩大转换始终会成功,因此它们不会引发异常。 收缩转换在失败时,最常见的是引发以下异常:

如果某个类或结构定义一个 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  

请参阅