Visual Basic 中的泛型型別 (Visual Basic)

「泛型型別」(Generic Type) 是單一程式設計項目,適用於針對多種資料型別執行相同的功能。 當您在定義泛型類別或程序時,不需要針對您想要執行該功能的每種資料型別定義不同的版本。

以下使用含有可更換頭的螺絲起子做比喻。 您會先檢查想要轉動的螺絲,然後針對該螺絲 (一字形、十字形或星字形) 選取正確的螺絲起子頭。 一旦您將正確的螺絲起子頭插入螺絲起子柄後,就可以用該螺絲起子執行相同的功能,也就是轉動螺絲。

設定為泛型工具的螺絲起子

一組泛用螺絲起子工具組的圖表

當您定義泛型型別後,您就會以一或多個資料型別進行參數化。 這樣可讓使用中的程式碼根據需求調整資料型別。 您的程式碼可以從泛型項目宣告數種不同的程式設計項目,而每個項目都可以作用於不同的資料型別集。 但是不論宣告的項目是使用哪種資料型別,都會執行相同的邏輯。

例如,您可能想要建立和使用可在特定資料型別 (例如 String) 上運作的佇列類別。 您可以從 System.Collections.Generic.Queue<T> 宣告此種類別,如下列範例所示。

Public stringQ As New System.Collections.Generic.Queue(Of String)

您現在可以使用 stringQ,以獨佔模式與 String 值一起運作。 因為 stringQ 是 String 特有的,而不是通用於 Object 值,因此您沒有晚期繫結或型別轉換。 這可以節省執行時間並且減少執行階段錯誤。

如需使用泛型型別的詳細資訊,請參閱 HOW TO:使用泛型類別 (Visual Basic)

泛型類別的範例

下列範例會顯示泛型類別的基本架構定義。

Public Class classHolder(Of t)
    Public Sub processNewItem(ByVal newItem As t)
        Dim tempItem As t
        ' Insert code that processes an item of data type t.
    End Sub
End Class

在先前的基本架構中,t 為「型別參數」(Type Parameter),也就是您在宣告類別時所提供之資料型別的替代符號 (Placeholder)。 您可以在程式碼的其他地方,宣告各種的 classHolder 版本,方法便是提供 t 的各種資料型別。 以下範例顯示兩個此類宣告。

Public integerClass As New classHolder(Of Integer)
Friend stringClass As New classHolder(Of String)

先前的陳述式會宣告「建構的類別」(Constructed Class),其中特定型別會取代型別參數。 這項取代會遍及建構之類別內的程式碼。 下列範例會顯示 processNewItem 程序在 integerClass 中的外觀。

Public Sub processNewItem(ByVal newItem As Integer)
    Dim tempItem As Integer
    ' Inserted code now processes an Integer item.
End Sub

如需更完整的範例,請參閱 HOW TO:定義可以在不同資料型別上提供完全相同功能的類別 (Visual Basic)

合格的程式設計項目

您可以定義並使用泛型類別、結構、介面、程序和委派 (Delegate)。 請注意,.NET Framework 會定義數個代表通用泛型項目的泛型類別、結構和介面。 System.Collections.Generic 命名空間 (Namespace) 會提供字典、清單、佇列和堆疊。 在定義自己的泛型項目之前,請查看它是否已存在 System.Collections.Generic 中。

程序並非型別,但您可以定義和使用泛型程序。 請參閱 Visual Basic 中的泛型程序

泛型型別的優點

泛型型別可以做為宣告數個不同程式設計項目的基礎,而每個項目會在特定的資料型別上運作。 泛型型別的替代型別如下:

  1. 在 Object 資料型別上運作的單一型別。

  2. 一組「特定型別」(Type-Specific) 的型別版本,每個版本都會個別進行編碼並於某一個特定的資料型別上運作,例如 String、Integer 或使用者定義的型別 (如 customer)。

泛型型別具有優於這些替代型別的下列優點:

  • 型別安全:泛型型別會強制進行編譯時期型別檢查。 以 Object 為基礎的型別會接受任何資料型別,而且您必須撰寫程式碼以檢查輸入資料型別是否可接受。 利用泛型型別,編譯器 (Compiler) 可以在執行階段前攔截不符的型別。

  • 效能:因為每個泛型型別都會針對某一種資料型別進行特製化,所以泛型型別不必進行資料的 Box 和 Unbox 處理。 根據 Object 的作業都必須進行輸入資料型別的 Box 處理,將這些資料型別轉換為 Object,並針對預定輸出的資料進行 Unbox 處理。 Box 和 Unbox 處理都會降低效能。

    以 Object 為基礎的型別也屬於晚期繫結的型別,這表示在執行階段存取這些型別的成員時,還需要額外的程式碼。 這也會降低效能。

  • 程式碼合併:泛型型別中的程式碼只能夠定義一次。 一組型別的特定型別版本必須在每個版本中複寫相同的程式碼,唯一的差異在於該版本的特定資料型別。 就泛型型別而言,特定型別的版本都是從原始泛型型別產生。

  • 重複使用程式碼:未相依於特殊資料型別的程式碼可以重複使用於各種資料型別 (如果是泛型型別的話)。 通常甚至可以重複使用於您原先未預期的資料型別。

  • IDE 支援:當您使用從泛型型別宣告之建構的型別時,整合式開發環境 (IDE) 便可以於開發程式碼時給予更多支援。 例如,IntelliSense™ 可以針對建構函式或方法的引數,顯示特定型別的選項。

  • 泛型演算法:與型別無關的抽象演算法可以做為良好的泛型型別。 例如,使用 IComparable 介面排序項目的泛型程序,可以用於實作 IComparable 的任何資料型別。

條件約束

雖然泛型型別定義中的程式碼應該盡可能與型別無關,但您可能會要求提供給泛型型別的任何資料型別具有某項功能。 例如,如果您想藉由比較兩個項目來達到排序或定序的目的,這兩個項目的資料型別就必須實作 IComparable 介面。 您可以將「條件約束」(Constraint) 加入至型別參數,以強制這項要求。

條件約束範例

下列範例會顯示類別的基本架構定義,該類別具有要求型別引數實作 IComparable 的條件約束。

Public Class itemManager(Of t As IComparable)
    ' Insert code that defines class members.
End Class

如果後續的程式碼嘗試從提供未實作 IComparable 之型別的 itemManager 建構類別,則編譯器會發出錯誤信號。

條件約束型別

您的條件約束可以利用任意組合指定下列需求:

  • 型別引數必須實作一或多個介面。

  • 型別引數必須為某個類別的型別,或繼承自至多一個類別。

  • 型別引數必須公開 (Expose) 無參數的建構函式,此建構函式可供據此建立物件的程式碼存取。

  • 型別引數必須是「參考型別」(Reference Type),或必須是「實值型別」(Value Type)。

如果您需要強制一個以上的要求,可以在大括號 ({ }) 內使用逗號分隔的「條件約束清單」(Constraint List)。 如需要求可存取的建構函式,可以在清單中包含 New 運算子 (Visual Basic) 關鍵字。 如需要求參考型別,您可以包含 Class 關鍵字。而若要要求實值型別,則可以包含 Structure 關鍵字。

如需條件約束的詳細資訊,請參閱型別清單 (Visual Basic)

多重條件約束的範例

下列範例會顯示泛型類別的基本架構定義,此類別具有型別參數的條件約束清單。 在建立此類別之執行個體的程式碼中,型別引數必須是參考型別,且必須實作 IComparableIDisposable 介面,並公開可存取的無參數建構函式。

Public Class thisClass(Of t As {IComparable, IDisposable, Class, New})
    ' Insert code that defines class members.
End Class

重要詞彙

泛型型別會引入並使用下列詞彙:

  • 泛型型別: 類別、結構、介面、程序或委派的定義,您會在進行宣告時提供至少一個資料型別。

  • 型別參數: 在泛型型別定義中,您在宣告型別時所提供之資料型別的替代符號 (Placeholder)。

  • 型別引數: 從泛型型別宣告建構的型別時,取代型別參數的特定資料型別。

  • 條件約束: 型別參數的條件,會限制您可以提供的型別引數。 條件約束可以要求型別引數必須實作特定介面、本身必須為或是必須繼承自特定類別、具有可存取的無參數建構函式,或為參考型別或實值型別。 您可以結合這些條件約束,但最多只能指定一個類別。

  • 建構的型別: 藉由提供型別參數的型別引數,從泛型型別宣告的類別、結構、介面、程序或委派。

請參閱

工作

疑難排解資料型別 (Visual Basic)

參考

資料型別摘要 (Visual Basic)

Of 子句 (Visual Basic)

As

Object 資料型別

概念

Visual Basic 中的資料型別

型別字元 (Visual Basic)

其他資源

資料型別實作 (Visual Basic)

Visual Basic 中的型別轉換

共變數和反變數 (C# 和 Visual Basic)