Evil 域

当Evil遇上先知

导航

VB 9.0新特性之局部类型推理(Local Type Inference)

Posted on 2008-06-12 21:55  Saar  阅读(862)  评论(1编辑  收藏  举报
在Visual Basic 9.0中,引入了类型推断的机制,在声明局部变量时,允许开发人员省略AS子句。如果一个局部变量声明时没有AS子句来明确声明其类型,编译器通过相应的赋值推测出来变量的类型,称为局部类型推理。例如,下面两行代码效果是一样的:
Dim name1 As String = "Springfield"
Dim name2 = "Springfield"
对于name2,编译器会推断出:name2是String类型的变量。
需要注意的是,这样的应用,只适用于局部变量中。如果将其使用到类的域中,则类型会被推断为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

第三到六行,定义了四个简单类型的变量。因为它们是局部变量,并且没有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没有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)

这样,屏幕输出会变成100.1和Hello两行。
说明一下,除非万不得已,否则,尽量不要用第二种方法来进行变量的声明。无论是从安全性、代码的效率、对Intellisence的支持等方面来说,第二种声明方法均不是一个好的选择。