在Visual Basic 9.0中,引入了类型推断的机制,在声明局部变量时,允许开发人员省略AS子句。如果一个局部变量声明时没有AS子句来明确声明其类型,编译器通过相应的赋值推测出来变量的类型,称为局部类型推理。例如,下面两行代码效果是一样的:
需要注意的是,这样的应用,只适用于局部变量中。如果将其使用到类的域中,则类型会被推断为Object。来看一个具体的例子:
首先,我们建立一个Notebook。这个类是用来帮助说明局部类型推理用的,如果你不想看,直接跳过。
大家注意在这个类的第8行,使用了局部类型推理,大家可以单步调试的看一下它的类型是什么^_^到底是Integer还是Object?动手试试就知道了。下面,我们进入正题,来看看如何使用局部类型推理:
第三到六行,定义了四个简单类型的变量。因为它们是局部变量,并且没有AS关键字来指定其类型,所以,这些变量的类型会分别被推断为:Integer、String、String、Double。
而第12行:
这样,屏幕输出会变成100.1和Hello两行。
说明一下,除非万不得已,否则,尽量不要用第二种方法来进行变量的声明。无论是从安全性、代码的效率、对Intellisence的支持等方面来说,第二种声明方法均不是一个好的选择。
Dim name1 As String = "Springfield"
Dim name2 = "Springfield"
对于name2,编译器会推断出:name2是String类型的变量。Dim name2 = "Springfield"
需要注意的是,这样的应用,只适用于局部变量中。如果将其使用到类的域中,则类型会被推断为Object。来看一个具体的例子:
首先,我们建立一个Notebook。这个类是用来帮助说明局部类型推理用的,如果你不想看,直接跳过。
Code
大家注意在这个类的第8行,使用了局部类型推理,大家可以单步调试的看一下它的类型是什么^_^到底是Integer还是Object?动手试试就知道了。下面,我们进入正题,来看看如何使用局部类型推理:
1 Sub Main()
2 'Infer simple type
3 Dim price = 16000
4 Dim brand = "Lenovo"
5 Dim type = "T61"
6 Dim weight = 2.3
7
8
9 'Dim myNoteBook = New Notebook() With {.Brand = brand, .Type = type, .Weight = weight, .Price = price}
10
11 'Infer an instance
12 Dim myNoteBook = New Notebook
13 myNoteBook.Brand = brand
14 myNoteBook.Price = price
15 myNoteBook.Type = type
16 myNoteBook.Weight = weight
17 Console.WriteLine("This is my Lenovo laptop:")
18 Console.WriteLine(myNoteBook.ToString())
19
20 'Infer in the using statement
21 Using tempLaptop = New Notebook
22 tempLaptop.Brand = "DELL"
23 tempLaptop.Price = 0
24 tempLaptop.Type = "Unknow"
25 tempLaptop.Weight = 0
26 Console.WriteLine("This is my temp laptop:")
27 Console.WriteLine(tempLaptop.ToString())
28 End Using
29
30
31
32 'Infer an array
33 Dim noteBooks = New Notebook() {myNoteBook, New Notebook, New Notebook}
34 noteBooks(1).Brand = "ASUS"
35 noteBooks(1).Price = 8500
36 noteBooks(1).Type = "A8"
37 noteBooks(1).Weight = 2.1
38
39 noteBooks(2).Brand = "HP"
40 noteBooks(2).Price = 7500
41 noteBooks(2).Type = "V3746TX"
42 noteBooks(2).Weight = 2.2
43
44 Console.WriteLine("These are laptops in the array:")
45 'Infer in loop
46 For Each laptop In noteBooks
47 Console.WriteLine(laptop.ToString())
48 Next
49
50 Console.ReadKey(True)
51 End Sub
2 'Infer simple type
3 Dim price = 16000
4 Dim brand = "Lenovo"
5 Dim type = "T61"
6 Dim weight = 2.3
7
8
9 'Dim myNoteBook = New Notebook() With {.Brand = brand, .Type = type, .Weight = weight, .Price = price}
10
11 'Infer an instance
12 Dim myNoteBook = New Notebook
13 myNoteBook.Brand = brand
14 myNoteBook.Price = price
15 myNoteBook.Type = type
16 myNoteBook.Weight = weight
17 Console.WriteLine("This is my Lenovo laptop:")
18 Console.WriteLine(myNoteBook.ToString())
19
20 'Infer in the using statement
21 Using tempLaptop = New Notebook
22 tempLaptop.Brand = "DELL"
23 tempLaptop.Price = 0
24 tempLaptop.Type = "Unknow"
25 tempLaptop.Weight = 0
26 Console.WriteLine("This is my temp laptop:")
27 Console.WriteLine(tempLaptop.ToString())
28 End Using
29
30
31
32 'Infer an array
33 Dim noteBooks = New Notebook() {myNoteBook, New Notebook, New Notebook}
34 noteBooks(1).Brand = "ASUS"
35 noteBooks(1).Price = 8500
36 noteBooks(1).Type = "A8"
37 noteBooks(1).Weight = 2.1
38
39 noteBooks(2).Brand = "HP"
40 noteBooks(2).Price = 7500
41 noteBooks(2).Type = "V3746TX"
42 noteBooks(2).Weight = 2.2
43
44 Console.WriteLine("These are laptops in the array:")
45 'Infer in loop
46 For Each laptop In noteBooks
47 Console.WriteLine(laptop.ToString())
48 Next
49
50 Console.ReadKey(True)
51 End Sub
第三到六行,定义了四个简单类型的变量。因为它们是局部变量,并且没有AS关键字来指定其类型,所以,这些变量的类型会分别被推断为:Integer、String、String、Double。
而第12行:
Dim myNoteBook = New Notebook
说明类的实体也可以使用局部类型推理来定义。它也可以写成:Dim myNoteBook As Notebook = New Notebook
而且在Using子句中,也可以使用局部类型推理,第21行便是个例子。局部类型推理可以用于声明数组,第33行代码,用New Notebook()来告诉编译器,noteBooks是一个数组。最后,它还有一个重要的用处,写在循环当中充当循环变量。第46~48行For Each循环便是一个例子。laptop在使用前并没有声明是什么类型,不过不要紧,因为它是In noteBooks的,而noteBooks是一个Notebook类型对象的集合,所以,编译器知道,laptop的类型是Notebook。
刚开始接触局部类型推理时,往往会有一种感觉:VB 9.0怎么成了弱类型的语言了?怎么可以不声明对象类型就进行赋值操作?其实,没有显式声明类型不等于弱类型。举个简单的例子:
Dim num1 = 100
num1 = 100.1
Console.WriteLine(num1)
num1 = "Hello"
Console.WriteLine(num1)
num1 = 100.1
Console.WriteLine(num1)
num1 = "Hello"
Console.WriteLine(num1)
首先,由于num1没有AS来指定其类型,所以,这里编译器会使用匿名类型推理,并且,由于赋给它的值是100,所以它是Integer类型的对象(这很关键)。
然后,对num1赋100.1,并输出到屏幕,结果,屏幕上输出的是:100而不是100.1,这是因为把一个浮点数赋值给一个Integer类型的变量,它会自动截断。而再往下让num1的值变成“Hello”,则会引发异常。所以,num1不是弱类型的,它仍然是强类型的,它的类型隐式声明了。
但是,偶尔会出现上述这种要给一个原来是Integer类型的变量赋String的情况,这个时候怎么处理呢?呵呵,也很简单,用AS!相应代码如下:
Dim num1 As Object = 100
num1 = 100.1
Console.WriteLine(num1)
num1 = "Hello"
Console.WriteLine(num1)
num1 = 100.1
Console.WriteLine(num1)
num1 = "Hello"
Console.WriteLine(num1)
这样,屏幕输出会变成100.1和Hello两行。
说明一下,除非万不得已,否则,尽量不要用第二种方法来进行变量的声明。无论是从安全性、代码的效率、对Intellisence的支持等方面来说,第二种声明方法均不是一个好的选择。
Little knowledge is dangerous.