每个值都有与之关联的类型,此类型定义分配给该值的空间大小,许多值可以表示为多种类型。例如,值 4 可以表示为整数或浮点值。在编程时,可能只需要整数,那么就得把小数转换为整数,有时可能还需要把类似"4"这样的字符串转换为一个数值,这就需要数据类型转换。
一、隐式转换和显示转换
隐式转换就是程序运行期间自行转换类型,不需要人为干预;而显示转换要求编译前指定由哪种类型转换成哪种类型,在代码书写中很容易识别。
下面的代码采用隐式转换:
'隐式转换成功
Dim int1 As Integer = Integer.MaxValue.ToString
Dim lng1 As Long = int1
'隐式转换失败,抛出错误
Dim lng2 As Long = Long.MaxValue
Dim int2 As Integer = lng2
Dim int1 As Integer = Integer.MaxValue.ToString需要把字符串转换成数值,Dim lng1 As Long = int1需要把 Integer类型转换成Long,都能隐式转换成功,而Dim int2 As Integer = lng2因为lng2的值超出了Integer数据类型的最大值,所以引发错误,转换失败。测试结果如图:
再看下面代码:
Sub Main()
Dim str As String
Dim int As Integer
Console.WriteLine("请输入数字:")
str = Console.ReadLine()
int = str
Console.WriteLine("您输入的数字是:" & int)
End Sub
当输入为数字时,程序正常运行,数据类型转换成功。如图:
但也许有人就是不按提示输入,偏偏输入了非数字的字符串,比如输入字母“A”,则会抛出错误,如图:
这种错误的发生是断断续续的,很难检查。
二、编程好习惯
编程前,先在“项目设计器”的“编译”页面进行如图所示的设置:
或者在代码最顶端增加以下代码:
Option Strict On
Option Infer Off
Option Explicit On
Module Module1
End Module
如图:
我们可以看到同样的代码这会无法通过编译,提示不能隐式转换,如图:
再来看一段代码:
Module Module1
Sub Main()
Dim intl As Integer
Int1 = 10
End Sub
End Module
当Option Explicit设置为OFF时,代码可以编译运行,但提示——未使用的局部变量:“intl”,代码中画绿色的波浪线,如图:
当然你一眼就会发现书写变量名错了,把字母l写成了数字1了,若是有几万的代码行,你再去找出这样的错误就难喽!
当Option Explicit设置为ON,Option Infer设置为OFF时,多了一条提示,如图:
这样就能很快发现是哪里出错。
Option Explicit:指定是否允许隐式声明变量。默认情况下,此选项设置为 “On”以要求显式声明变量;如果变量在使用前没有声明,此设置会导致编译器报告错误。 选择 “Off”可允许隐式声明变量。
Option Strict:指定是否允许许可类型语义。默认情况下,此选项设置为 “Off”,表示允许许可类型语义。 选择 “On”可以限制隐式类型转换,即要求显式收缩转换并且不允许后期绑定。
Option Infer:指定是否允许变量声明中的局部类型推理。默认情况下,此选项设置为 “On”,表示允许使用局部类型推理。 选择 “Off”可阻止局部类型推理。
Option Explicit设置为ON的话必须同时把Option Infer设置为OFF,否则效果会互相抵消。这样做的好处多多,就不再一一举例说明了。
三、 使用System .Convert 类的方法进行类型转换
System .Convert 类可以将一个基本数据类型转换为另一个基本数据类型。
Convert 类提供了一种与语言无关的方式来执行基类型之间的转换,并且该类可用于面向公共语言运行时的所有语言。
Convert 类的静态方法用于支持与 .NET Framework 的基础数据类型之间的转换。 受支持的基类型是 Boolean、 Char、 SByte、 Byte、 Int16、 Int32、 Int64、 UInt16、 UInt32、 UInt64、 Single、 Double、 Decimal、 DateTime 和 String。
Convert 类的方法代码格式为:Convert.To+数据类型(要转换的值);
如:Convert.ToInt32(“32”)。
上面的代码因为把Option Strict设置为On,会抛出一个错误,修改为如下代码:
Dim str As String
Dim int As Integer
Console.WriteLine("请输入数字:")
str = Console.ReadLine()
int = Convert.ToInt32(str)
Console.WriteLine("您输入的数字是:" & int)
当输入非数字时和隐式转换一样会抛出一个运行时错误,所以即使使用显式的类型转换,也要注意对错误的处理。代码如下:
Dim str As String
Dim int As Integer
line: Console.WriteLine("请输入数字:")
str = Console.ReadLine()
Try
int = Convert.ToInt32(str)
Catch
GoTo line
End Try
Console.WriteLine("您输入的数字是:" & int)
只要输入的是非数字就会要求重新输入,如图:
抛砖引玉,看官可以举一反三进行其他类型的转换。
以下内容来源于帮助页:
根据运行时基类型和目标基类型的值,对特定转换方法的实际调用会产生五种结果之一。这五种结果如下:
1、无转换。当尝试将一个类型转换为其本身时(如使用 Int32 类型参数调用 Convert .ToInt32(Int32) )会发生这种情况。 在这种情况下,此方法只是返回原始类型实例。
2、一个 InvalidCastException。 当不支持特定转换时会发生这种情况。
以下转换会引发 InvalidCastException:
将 Char 转换为 Boolean、 Single、 Double、 Decimal 或 DateTime。
将 Boolean、 Single、 Double、 Decimal 或 DateTime 转换为 Char。
将 DateTime 转换为 String 以外的任何其他类型。
将 String 以外的任何其他类型转换为 DateTime。
3、一个 FormatException。 当由于字符串格式不正确而导致将字符串值转换为任何其他基类型的尝试失败时,会发生该异常。
以下转换会引发该异常:
要转换为 Boolean 值的字符串不等于 Boolean .TrueString 或 Boolean .FalseString 。
要转换为 Char 值的字符串由多个字符组成。
要转换为任何数值类型的字符串没有被识别为有效数字。
要转换为 DateTime 的字符串没有被识别为有效日期和时间值。
4、转换成功。对于前面结果中未列出的两个不同基类型之间的转换,所有扩大转换和不会导致数据丢失的收缩转换都将成功,此方法将返回目标基类型的值。
5、一个 OverflowException。 当收缩转换导致数据丢失时会发生这种情况。例如,尝试将值为 10000 的 Int32 实例转换为 Byte 类型会引发 OverflowException,因为 10000 超出了 Byte 数据类型的范围。
注意:如果数字类型转换导致精度丢失(即某些最低有效位丢失),不引发异常。但是,如果结果超出了特定转换方法的返回值类型所能表示的范围,则将引发异常。例如,当将 Double 转换为 Single 时,可能会发生精度丢失,但并不引发异常。 但是,如果 Double 的值太大,无法由 Single 表示,则将引发溢出异常。
旧版本的VB6.0里如Cstr的类型转换函数在VB.NET中还是可以用的,不过为了兼容其他语言程序员的感受,建议使用Convert类来进行基本类型之间的转换。
四、Parse和TryParse方法
大多数的值类型,至少在.NET Framework中的值类型,都具有两个静态分析方法(Parse 和 TryParse),可以使用它们将字符串转换为指定的值类型。
特别说明:Parse 和 TryParse方法只能用于值类型,也就是说只能把字符串转换为相应的值类型。
使用Parse方法时,如果数据不能转换会抛出一个运行时错误。如:
Dim str As String
Dim int As Integer
line: Console.WriteLine("请输入数字:")
str = Console.ReadLine()
Try
int = Integer.Parse(str)
Catch
GoTo line
End Try
Console.WriteLine("您输入的数字是:" & int)
使用TryParse方法可以免去捕获错误语句,因为他有两个参数,返回一个布尔值,表示转换是否成功,如果转换成功,就会把新值存储在该方法的第二个参数。如:
Dim str As String
Dim int As Integer
Dim bln As Boolean
line: Console.WriteLine("请输入数字:")
str = Console.ReadLine()
bln = Integer.TryParse(str, int)
If bln Then
Console.WriteLine("您输入的数字是:" & int)
Else
GoTo line
End If
在不确定是否能转换成功,而又想省去错误捕获代码的建议使用TryParse方法。
五、DirectCast和TryCast方法
DirectCast和TryCast方法是基于继承或实现的类型转换操作。仅适用于引用类型,不适用于值类型。如:
'转换失败
Dim q As Object = 2.37
Dim i As Integer = CType(q, Integer)
Dim j As Integer = DirectCast(q, Integer)
'转换成功
Dim f As New System.Windows.Forms.Form
Dim c As System.Windows.Forms.Control
c = DirectCast(f, System.Windows.Forms.Control)
第一个 DirectCast 在运行时失败是因为 Double 的运行时类型与 Integer 没有继承关系(值类型)。 第二个 DirectCast 成功是因为它从 Form 类型转换为 Control 类型,而 Form 继承自该类型(引用类型)。
TryCast方法不会引发错误,如果转换失败则返回Nothing。如:
Dim f As New System.Windows.Forms.Form
Dim c As System.Windows.Forms.Control = TryCast(f, System.Windows.Forms.Control)
If c Is Nothing Then
MessageBox.Show("转换失败!")
End If
六、CType 函数
CType 函数可以说是全能的类型转换函数,即适用于值类型,也适用于引用类型。工作方式与DirectCast方法类似。
CType(expression, typename)
参数:expression——任何有效的表达式。如果 expression 的值超出 typename 允许的范围,Visual Basic 将引发异常。
typename——任何在 Dim 语句的 As 子句内合法的表达式,即任何数据类型、对象、结构、类或接口的名称。
测试代码如:
'值类型
Dim q As Object = 2.37
Dim i As Integer = CType(q, Integer)
'Dim j As Integer = DirectCast(q, Integer)
'引用类型
Dim f As New System.Windows.Forms.Form
Dim c As System.Windows.Forms.Control
Dim d As System.Windows.Forms.Control
c = CType(f, System.Windows.Forms.Control)
d = DirectCast(f, System.Windows.Forms.Control)
七、Object.ToString 方法
Object.ToString 方法可以将其他类型数据转换成字符串数据类型。每个从 System.Object 派生的类型都自动继承无参数的 ToString 方法,该方法在默认情况下以字符串的形式返回对象的名称或值类型数据的值。如:
Dim int As Integer = 10
Dim bln As Boolean = True
Dim obj As New Object
Console.WriteLine(int.ToString)
Console.WriteLine(bln.ToString)
Console.WriteLine(obj.ToString)