-
扩大转换和收缩转换 (Visual Basic)
进行类型转换时的一个重要注意事项是转换的结果是否在目标数据类型的范围内。 “扩大转换”将值更改为可提供原始数据的任何可能值的数据类型。 而“收缩转换”将值更改为可能无法具有某些可能值的数据类型。
扩大转换
下表显示了标准的扩大转换。
数据类型 |
扩大到下列数据类型 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 |
Integer, Long, Decimal, Single, Double2 |
UInteger |
UInteger, Long, ULong, Decimal, Single, Double 2 |
Long |
Long, Decimal, Single, Double 2 |
ULong |
ULong, Decimal, Single, Double 2 |
Decimal |
Decimal, Single, Double 2 |
Single |
Single, Double |
Double |
Double |
任何枚举类型 (Enum) |
其基础整型和基础类型扩大到的任何类型 |
Char |
Char, String |
Char 数组 |
Char 数组、String |
任何类型 |
对象 |
任何派生类型 |
它派生自的任何基类型 3 |
任何类型 |
它实现的任何接口 |
Nothing |
任何数据类型或对象类型 |
1 按照定义,每种数据类型都扩大到自身。
2 从 Integer、UInteger、Long、ULong 或 Decimal 转换为 Single 或 Double 可能会导致精度降低,但大小决不会损失。 从这种意义上讲,它们不会导致信息丢失。
3 从派生类型到它的基类型的转换正在扩大,这看起来可能让人吃惊。 原因是派生类型包含基类型的所有成员,因此它有资格作为基类型的实例。 在相反的方向,基类型不包含由派生类型定义的任何新成员。
扩大转换在运行时始终是成功的,且从不会导致数据丢失。 可以始终隐式执行它们,而不管 Option Strict 语句 将类型检查开关设置为 On 还是 Off。
收缩转换
标准的收缩转换包括:
-
上表中扩大转换的相反方向(每种类型扩大到自身除外)
-
Boolean 和任何 numeric 类型之间的双向转换
-
从任何 numeric 类型到任何枚举类型 (Enum) 的转换。
-
在 String 和任何 numeric 类型、Boolean 或 Date 之间的双向转换
-
从数据类型或对象类型到其派生类型的转换
收缩转换在运行时并不总会成功,可能会失败或导致数据丢失。 如果目标数据类型无法接收正转换的值,将会出错。 例如,数字转换可能导致溢出。 除非 Option Strict 语句 将类型检查开关设置为 Off,否则编译器不允许您隐式执行收缩转换。
提示
对于从 For Each…Next 集合中的元素到循环控制变量的转换,禁止显示收缩转换错误。 有关更多信息和示例,请参见 For Each...Next 语句 (Visual Basic)中的“收缩转换”一节。
何时使用收缩转换
知道源值可以转换为目标数据类型而不会出错或导致数据丢失时,可使用收缩转换。 例如,如果有一个 String 并且知道其中包含“True”或“False”,则可以使用 CBool 关键字将其转换为 Boolean。
转换过程中的异常
由于扩大转换始终都是成功的,它们不会引发异常。 当收缩转换失败时,最常引发下列异常:
-
InvalidCastException - 如果在两种类型之间未定义转换
-
OverflowException - (仅限整型)如果对于目标类型来说转换后的值太大
如果类或结构将 CType 函数 (Visual Basic) 定义为充当该类或结构之间的转换运算符,则该 CType 会引发它认为适当的任何异常。 此外,该 CType 可能会调用 Visual Basic 函数或 .NET Framework 方法,这些函数或方法又可能引发各种异常。