Generic Types - Visual Basic (original) (raw)

A generic type is a single programming element that adapts to perform the same functionality for multiple data types. When you define a generic class or procedure, you don't have to define a separate version for each data type for which you might want to perform that functionality.

An analogy is a screwdriver set with removable heads. You inspect the screw and select the correct head for that screw (slotted, crossed, starred). Once you insert the correct head in the screwdriver handle, you perform the exact same function with the screwdriver, namely turning the screw.

Diagram of a screwdriver set with different heads.

When you define a generic type, you parameterize it with one or more data types. Type parameters allow code to tailor the data types to its requirements. Your code can declare several different programming elements from the generic element, each one acting on a different set of data types. But the declared elements all perform the identical logic, no matter what data types they're using.

For example, you might want to create and use a queue class that operates on a specific data type such as String. You can declare such a class from System.Collections.Generic.Queue, as the following example shows.

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

You can now use stringQ to work exclusively with String values. Because stringQ is specific for String instead of being generalized for Object values, you don't have late binding or type conversion. Generic types save execution time and reduce run-time errors.

For more information on using a generic type, see How to: Use a Generic Class.

Example of a generic class

The following example shows a skeleton definition of a generic class.

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

In the preceding skeleton, t is a type parameter, that is, a placeholder for a data type that you supply when you declare the class. Elsewhere in your code, you can declare various versions of classHolder by supplying various data types for t. The following example shows two such declarations.

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

The preceding statements declare constructed classes, in which a specific type replaces the type parameter. This replacement is propagated throughout the code within the constructed class. The following example shows what the processNewItem procedure looks like in integerClass.

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

For a more complete example, see How to: Define a Class That Can Provide Identical Functionality on Different Data Types.

Eligible programming elements

You can define and use generic classes, structures, interfaces, procedures, and delegates. .NET defines several generic classes, structures, and interfaces that represent commonly used generic elements. The System.Collections.Generic namespace provides dictionaries, lists, queues, and stacks. Before defining your own generic element, see if it's already available in System.Collections.Generic.

Procedures aren't types, but you can define and use generic procedures. See Generic Procedures in Visual Basic.

Advantages of generic types

A generic type serves as a basis for declaring several different programming elements, each of which operates on a specific data type. The alternatives to a generic type are:

  1. A single type operating on the Object data type.
  2. A set of type-specific versions of the type. Each version is individually coded and operating on one specific data type such as String, Integer, or a user-defined type such as customer.

A generic type has the following advantages over these alternatives:

Constraints

Although the code in a generic type definition should be as type-independent as possible, you might need to require a certain capability of any data type supplied to your generic type. For example, if you want to compare two items to sort or collate, their data type must implement the IComparable interface. You can enforce this requirement by adding a constraint to the type parameter.

Example of a constraint

The following example shows a skeleton definition of a class with a constraint that requires the type argument to implement IComparable.

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

If subsequent code attempts to construct a class from itemManager supplying a type that doesn't implement IComparable, the compiler signals an error.

Types of constraints

Your constraint can specify the following requirements in any combination:

C# code can declare that a type argument must be an unmanaged type. Visual Basic enforces this constraint for Visual Basic code that uses a generic type or method that was defined with this constraint (in C#). However, you can't declare an unmanaged constraint on a type parameter in Visual Basic.

If you need to impose more than one requirement, you use a comma-separated constraint list inside braces ({ }). To require an accessible constructor, you include the New Operator keyword in the list. To require a reference type, you include the Class keyword; to require a value type, you include the Structure keyword.

For more information on constraints, see Type List.

Example of multiple constraints

The following example shows a skeleton definition of a generic class with a constraint list on the type parameter. In the code that creates an instance of this class, the type argument must implement both the IComparable and IDisposable interfaces, be a reference type, and expose an accessible parameterless constructor.

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

Important terms

Generic types introduce and use the following terms:

See also