向Visual Basic程式員介紹泛型(一)
最後更新:2017-02-28
來源:互聯網
上載者:User
visual|程式|程式員 此文檔是Sean Campbell, Scott Swigart, Kris Horrocks, Derek Hatchard, and Peter Bernhardt.等人創作的《向Microsoft Visual Basic程式員介紹Whidbey》一書中的樣章,著作權歸原作者和出版社所有。轉載請註明此聲明。
本文用通俗的用語和大量的執行個體向Visual Basic程式員介紹了下一版Visual Basic.Net中將要增加的新功能——泛型。此文章可以協助廣大VB使用者瞭解泛型,以便將來將泛型應用到自己的應用程式中。
應用:泛型
此應用展示了在Visual Basic.Net 中新增加的泛型功能。
新概念
在開始實現泛型以前,有必要花一點時間分析一下為什麼要在Visual Basic.Net中增加這一功能。泛型技術源於需要用一種一般的方法處理對象各種可能的類型,而不需要關心他們具體的類型。比如在Visual Basic 6.0中,你能夠用一個Collection類儲存任何類型的對象。
Visual Basic 6.0 的集合
Visual Basic 6.0 確實允許你將任何東西儲存在一個Collection中。但是,Collection類有幾個限制。我們用一個例子來說明如何將這個Employee類儲存在集合中:
‘ Visual Basic 6.0 代碼:類別模組Employee
Public SSN As String
Public FirstName As String
Public LastName As String
Public Salary As Currency
將這個類儲在集合中的方法顯得非常直接。
‘ Visual Basic 6.0 代碼
Dim employees As New Collection
Dim emp As Employee
Set emp = New Employee
emp.SSN = "111-11-1111"
emp.FirstName = "Scott"
emp.LastName = "Swigart"
emp.Salary = 50000
employees.Add emp, emp.SSN
這段代碼首先建立了一個Collection的執行個體employees。接著Employee類建立了一個執行個體,並設定了一些資料。最後,Employee對象被添加到Collection,指定emp.SSN屬性作為關鍵字。下面的代碼展示了如何從Collection取出這個Employee對象的執行個體:
‘ Visual Basic 6.0 代碼
Dim emp2 As Employee
Set emp2 = employees("111-11-1111")
現在我們一起來研究一下Visual Basic 6.0的這種集合有什麼限制。首先,你的初衷是讓employees這個集合只儲存Employee類型的對象。但是沒有任何機制可以防止將一個別的類型的對象放入這個employees集合,也沒有任何東西可以告訴你從這個集合中取出的資料是什麼類型。下面的代碼照樣可以正確編譯:
Dim s As String
s = employees("111-11-1111")
雖然開發人員可以很明確地知道這不能正確工作,但沒有辦法讓編譯器發現這個問題。這樣會發生一個執行階段錯誤。集合的使用同樣限制了智能感知技術的發揮。看看下面這段代碼:
employees("111-11-1111").LastName = "SomeoneElse"
這說明你能直接編輯集合中的項目。但是,IDE的智能感知不能協助你選擇LastName屬性。再一次重申,以前的Visual Basic 中集合可以存放任何東西。
使用集合的兩個最大的限制是效能和靈活性方面的損失。集合雖然容易使用,但作為一個動態數組使用時效能非常差。集合的設計使它更像是一個字典,所以當你需要的資料結構類似堆棧或隊列時,它也不是一個很好的選擇。
架構中的集合
.Net架構1.0/1.1通過增加集合的種類解決了一部分問題。新引入System.Collections命名空間以後,你就可以建立更多類型的集合,比如數組表、位元組、雜湊表、隊列、排序表和堆棧。下表列出了這些類型的用法:
集合名稱
用途
ArrayList
數組表能夠建立動態增大的數組。
BitArray
位元組是經過最佳化的,專用於儲存布爾值(真/假)的數組。
HashTable
雜湊表和Visual Basic 6.0中的Collection類非常相似。它允許你通過關鍵字找得到對應的值。不過關鍵字和值 還是任意類型的。
SortedList
排序表和雜湊表非常類似,唯一不同的是它的關鍵字總是排序的。這意味著當你用For …Each文法遍曆整個集合時,得到的項目總是經過排序的。
Queue
隊列是一種能讓被儲存的對象先進先出的集合。
Stack
堆棧是一種能讓被儲存的對象後進先出的集合。
.Net 架構1.0/1.1已經解決了Visual Basic 6.0中的集合在靈活性方面的限制,但是,這些集合仍然是弱類型的,因此你還是可以將任何東西存放到一個ArrayList中,雖然在一個指定的應用中,只有儲存唯一的類型才有意義。
你真正想要是指定每個關鍵字必須都是String而且每個值都是Employee類型。在.Net架構1.0和1.1種,你只有建立自己的類,當然這種方法有些繁瑣。如果使用新的.Net架構1.2,這個問題可以用很少的代碼來解決,方法就是使用泛型。
深入代碼
泛型能夠提供嚴格的類型檢查,更好的智能感知功能和更好的效能,就如上一節中介紹的一樣。換句話說,他們超越了以前所有集合類所能提供的優點。
感受泛型
接下來你將看到,當你建立一個泛型集合的執行個體的時候,你需要提供一些資訊以便集合類能夠被強型別化。這樣做有很多優點,包括在編譯階段更多的檢查以確保建立更安全和更可靠的代碼,更好的智能感知以及更好的效能。有必要提及.Net架構1.2中是在以前版本的基礎上新增加泛型集合。.Net架構1.2不會強迫你使用泛型。
如果你想使用泛型型別,首先需要包含System.Collections.Generic這個命名空間。這允許訪問帶有泛型功能的Dictionary、List、Queue、SortedDictionary和Stack類。下面btnConsumeGenerics_Click事件中的代碼提供了一個使用泛型字典的例子:
‘ Visual Basic .NET 8.0 代碼
Private Sub btnConsumeGenerics_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConsumeGenerics.Click
Dim employees As New Dictionary(Of String, Employee)
Dim emp As Employee
emp = New Employee
emp.SSN = "111-11-1111"
emp.FirstName = "Scott"
emp.LastName = "Swigart"
emp.Salary = 50000
employees.Add(emp.SSN, emp)
Dim emp2 As Employee
emp2 = employees.Item("111-11-1111")
Dim s As String
's = employees.Item("111-11-1111") ' This is now a syntax error
employees.Item("111-11-1111").LastName = "SomeoneElse"
End Sub
深入查看這段代碼,你會注意到一些泛型技術中相當有趣的東西。首先泛型的類型是用這樣的方法具體化的:
Dim employees As New Dictionary(Of String, Employee)
這可以翻譯成“建立一個Dictionary,它的關鍵字是String類型,值是Employee類型”。任何時候試圖儲存一個不是Employee類型的對象都將導致編譯錯誤。有必要重申,如果使用了泛型,你再用錯類型得到的將是編譯錯誤而不是執行階段錯誤。事實上下面這段代碼除非被注釋掉,否則不會通過編譯,就如同編譯器知道Dictionary是專用於儲存Employee對象,而不是String:
's = employees.Item("111-11-1111") ' This is now a syntax error
更進一步,你現在能獲得全面的能感知支援。如果你輸入“employees.Item(“111-11-1111”).”,將自動彈出Employee類型的成員,這說明Visual Studio知道Dictionary現在是專門儲存Employee類的集合。
(未完,接《向Visual Basic程式員介紹泛型(二)》)