如何:定義可以在不同資料類型上提供完全相同功能的類別 (Visual Basic)
您可以定義用於建立物件的類別,而這些物件會在不同資料型別上提供相同功能。 若要這樣做,可以在定義中指定一或多個「型別參數」(Type Parameter)。 然後,類別就可以當做使用不同資料型別之物件的樣板 (Template)。 用此方式定義的類別即稱為「泛型類別」(Generic Class)。
定義泛型類別的優點是只要定義一次,程式碼就可以用它來建立許多使用各種資料型別的物件。 這樣所產生的效能,會比使用 Object 型別定義類別的效能更好。
除了類別之外,您也可以定義並使用泛型結構、介面、程序和委派 (Delegate)。
若要使用型別參數定義類別
以一般方式定義類別。
將 (Of typeparameter) 緊接著加在類別名稱後面,以指定型別參數。
如果有一個以上的型別參數,請使用括號將逗號分隔清單括起來。 請不要重複 Of 關鍵字。
如果程式碼是在型別參數上執行作業,而不是簡單指派 (Assignment),請在型別參數後面加上 As 子句以加入一或多個「條件約束」(Constraint)。 條件約束保證提供給該型別參數的型別,會滿足下列需求:
支援程式碼所執行的作業 (例如 >)
支援程式碼所存取的成員 (例如方法)
公開 (Expose) 無參數建構函式 (Constructor)
如果未指定任何條件約束,則程式碼唯一可以使用的作業和成員就是 Object 資料類型所支援的作業和成員。 如需詳細資訊,請參閱類型清單 (Visual Basic)。
辨識每個要使用所提供型別宣告的類別成員,並將它宣告為 As typeparameter。 這適用於內部儲存區、程序參數和傳回值。
請確定程式碼只會使用任何資料型別所支援的作業和方法,且可以將這些資料型別提供給 itemType。
下列範例會定義用於管理極簡單清單的類別。 它會將清單保留在內部陣列 items 中,而透過使用的程式碼則可以宣告清單項目的資料型別。 參數化建構函式允許使用程式碼來設定 items 的上限 (Upper Bound),而預設建構函式則將這個項目設定成 9 (總共是 10 個項目)。
Public Class simpleList(Of itemType) Private items() As itemType Private top As Integer Private nextp As Integer Public Sub New() Me.New(9) End Sub Public Sub New(ByVal t As Integer) MyBase.New() items = New itemType(t) {} top = t nextp = 0 End Sub Public Sub add(ByVal i As itemType) insert(i, nextp) End Sub Public Sub insert(ByVal i As itemType, ByVal p As Integer) If p > nextp OrElse p < 0 Then Throw New System.ArgumentOutOfRangeException("p", " less than 0 or beyond next available list position") ElseIf nextp > top Then Throw New System.ArgumentException("No room to insert at ", "p") ElseIf p < nextp Then For j As Integer = nextp To p + 1 Step -1 items(j) = items(j - 1) Next j End If items(p) = i nextp += 1 End Sub Public Sub remove(ByVal p As Integer) If p >= nextp OrElse p < 0 Then Throw New System.ArgumentOutOfRangeException("p", " less than 0 or beyond last list item") ElseIf nextp = 0 Then Throw New System.ArgumentException("List empty; cannot remove ", "p") ElseIf p < nextp - 1 Then For j As Integer = p To nextp - 2 items(j) = items(j + 1) Next j End If nextp -= 1 End Sub Public ReadOnly Property listLength() As Integer Get Return nextp End Get End Property Public ReadOnly Property listItem(ByVal p As Integer) As itemType Get If p >= nextp OrElse p < 0 Then Throw New System.ArgumentOutOfRangeException("p", " less than 0 or beyond last list item") End If Return items(p) End Get End Property End Class
您可以從 simpleList 中宣告類別以保留 Integer 值的清單,並宣告另一個類別以保留 String 值的清單,然後再宣告另一個類別以保留 Date 值。 除了清單成員的資料型別外,從所有這些類別中建立的物件的行為都相同。
使用程式碼提供給 itemType 的型別引數可以是內建 (Intrinsic) 型別 (例如 Boolean 或 Double)、結構、列舉型別 (Enumeration) 或任何型別的類別 (包含應用程式定義的類別)。
您可以使用下列程式碼來測試類別 simpleList。
Public Sub useSimpleList() Dim iList As New simpleList(Of Integer)(2) Dim sList As New simpleList(Of String)(3) Dim dList As New simpleList(Of Date)(2) iList.add(10) iList.add(20) iList.add(30) sList.add("First") sList.add("extra") sList.add("Second") sList.add("Third") sList.remove(1) dList.add(#1/1/2003#) dList.add(#3/3/2003#) dList.insert(#2/2/2003#, 1) Dim s = "Simple list of 3 Integer items (reported length " & CStr(iList.listLength) & "):" & vbCrLf & CStr(iList.listItem(0)) & vbCrLf & CStr(iList.listItem(1)) & vbCrLf & CStr(iList.listItem(2)) & vbCrLf & "Simple list of 4 - 1 String items (reported length " & CStr(sList.listLength) & "):" & vbCrLf & CStr(sList.listItem(0)) & vbCrLf & CStr(sList.listItem(1)) & vbCrLf & CStr(sList.listItem(2)) & vbCrLf & "Simple list of 2 + 1 Date items (reported length " & CStr(dList.listLength) & "):" & vbCrLf & CStr(dList.listItem(0)) & vbCrLf & CStr(dList.listItem(1)) & vbCrLf & CStr(dList.listItem(2)) MsgBox(s) End Sub