Sideway from Sideway
Draft for Information Only


VB.NET Type of Generic Data
  Generic Types in Visual Basic
 Example of a Generic Class
 Eligible Programming Elements
 Advantages of Generic Types
  Example of a Constraint
  Types of Constraints
  Example of Multiple Constraints
 Important Terms
 See also
  How to: Define a Class That Can Provide Identical Functionality on Different Data Types
  To define a class with a type parameter
 See also
  How to: Use a Generic Class
  To use a class that takes a type parameter
 See also
  Generic Procedures in Visual Basic
 Type Inference
 See also

VB.NET Type of Generic Data

Generic Types in Visual Basic

A generic type is a single programming element that adapts to perform the same functionality for a variety of data types. When you define a generic class or procedure, you do not 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 you need to turn 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. This allows the using 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 are 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<T>, 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 do not have late binding or type conversion. This saves execution time and reduces 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. Note that the .NET Framework 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 is already available in System.Collections.Generic.

Procedures are not 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 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:

  • Type Safety. Generic types enforce compile-time type checking. Types based on Object accept any data type, and you must write code to check whether an input data type is acceptable. With generic types, the compiler can catch type mismatches before run time.

  • Performance. Generic types do not have to box and unbox data, because each one is specialized for one data type. Operations based on Object must box input data types to convert them to Object and unbox data destined for output. Boxing and unboxing reduce performance.

    Types based on Object are also late-bound, which means that accessing their members requires extra code at run time. This also reduces performance.

  • Code Consolidation. The code in a generic type has to be defined only once. A set of type-specific versions of a type must replicate the same code in each version, with the only difference being the specific data type for that version. With generic types, the type-specific versions are all generated from the original generic type.

  • Code Reuse. Code that does not depend on a particular data type can be reused with various data types if it is generic. You can often reuse it even with a data type that you did not originally predict.

  • IDE Support. When you use a constructed type declared from a generic type, the integrated development environment (IDE) can give you more support while you are developing your code. For example, IntelliSense can show you the type-specific options for an argument to a constructor or method.

  • Generic Algorithms. Abstract algorithms that are type-independent are good candidates for generic types. For example, a generic procedure that sorts items using the IComparable interface can be used with any data type that implements IComparable.


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 for the purpose of sorting or collating, 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 does not implement IComparable, the compiler signals an error.

Types of Constraints

Your constraint can specify the following requirements in any combination:

  • The type argument must implement one or more interfaces

  • The type argument must be of the type of, or inherit from, at most one class

  • The type argument must expose a parameterless constructor accessible to the code that creates objects from it

  • The type argument must be a reference type, or it must be a value type

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:

  • Generic Type. A definition of a class, structure, interface, procedure, or delegate for which you supply at least one data type when you declare it.

  • Type Parameter. In a generic type definition, a placeholder for a data type you supply when you declare the type.

  • Type Argument. A specific data type that replaces a type parameter when you declare a constructed type from a generic type.

  • Constraint. A condition on a type parameter that restricts the type argument you can supply for it. A constraint can require that the type argument must implement a particular interface, be or inherit from a particular class, have an accessible parameterless constructor, or be a reference type or a value type. You can combine these constraints, but you can specify at most one class.

  • Constructed Type. A class, structure, interface, procedure, or delegate declared from a generic type by supplying type arguments for its type parameters.

See also

How to: Define a Class That Can Provide Identical Functionality on Different Data Types

You can define a class from which you can create objects that provide identical functionality on different data types. To do this, you specify one or more type parameters in the definition. The class can then serve as a template for objects that use various data types. A class defined in this way is called a generic class.

The advantage of defining a generic class is that you define it just once, and your code can use it to create many objects that use a wide variety of data types. This results in better performance than defining the class with the Object type.

In addition to classes, you can also define and use generic structures, interfaces, procedures, and delegates.

To define a class with a type parameter

  1. Define the class in the normal way.

  2. Add (Of typeparameter) immediately after the class name to specify a type parameter.

  3. If you have more than one type parameter, make a comma-separated list inside the parentheses. Do not repeat the Of keyword.

  4. If your code performs operations on a type parameter other than simple assignment, follow that type parameter with an As clause to add one or more constraints. A constraint guarantees that the type supplied for that type parameter satisfies a requirement such as the following:

    • Supports an operation, such as >, that your code performs

    • Supports a member, such as a method, that your code accesses

    • Exposes a parameterless constructor

    If you do not specify any constraints, the only operations and members your code can use are those supported by the Object Data Type. For more information, see Type List.

  5. Identify every class member that is to be declared with a supplied type, and declare it As typeparameter. This applies to internal storage, procedure parameters, and return values.

  6. Be sure your code uses only operations and methods that are supported by any data type it can supply to itemType.

    The following example defines a class that manages a very simple list. It holds the list in the internal array items, and the using code can declare the data type of the list elements. A parameterized constructor allows the using code to set the upper bound of items, and the parameterless constructor sets this to 9 (for a total of 10 items).

Public Class simpleList(Of itemType)
  Private items() As itemType
  Private top As Integer
  Private nextp As Integer
  Public Sub New()
  End Sub
  Public Sub New(ByVal t As Integer)
    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 ", 
    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 ", 
    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
      Return nextp
    End Get
  End Property
  Public ReadOnly Property listItem(ByVal p As Integer) As itemType
      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

You can declare a class from simpleList to hold a list of Integer values, another class to hold a list of String values, and another to hold Date values. Except for the data type of the list members, objects created from all these classes behave identically.

The type argument that the using code supplies to itemType can be an intrinsic type such as Boolean or Double, a structure, an enumeration, or any type of class, including one that your application defines.

You can test the class simpleList with the following code.

  1. 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)
      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))
    End Sub

See also

How to: Use a Generic Class

A class that takes type parameters is called a generic class. If you are using a generic class, you can generate a constructed class from it by supplying a type argument for each of these parameters. You can then declare a variable of the constructed class type, and you can create an instance of the constructed class and assign it to that variable.

In addition to classes, you can also define and use generic structures, interfaces, procedures, and delegates.

The following procedure takes a generic class defined in the .NET Framework and creates an instance from it.

To use a class that takes a type parameter

  1. At the beginning of your source file, include an Imports Statement (.NET Namespace and Type) to import the System.Collections.Generic namespace. This allows you to refer to the System.Collections.Generic.Queue<T> class without having to fully qualify it to differentiate it from other queue classes such as System.Collections.Queue.

  2. Create the object in the normal way, but add (Of type) immediately after the class name.

    The following example uses the same class (System.Collections.Generic.Queue<T>) to create two queue objects that hold items of different data types. It adds items to the end of each queue and then removes and displays items from the front of each queue.

  1. Public Sub usequeue()
      Dim queueDouble As New System.Collections.Generic.Queue(Of Double)
      Dim queueString As New System.Collections.Generic.Queue(Of String)
      queueString.Enqueue("First string of three")
      queueString.Enqueue("Second string of three")
      queueString.Enqueue("Third string of three")
      Dim s As String = "Queue of Double items (reported length " &
          CStr(queueDouble.Count) & "):"
      For i As Integer = 1 To queueDouble.Count
        s &= vbCrLf & CStr(queueDouble.Dequeue())
      Next i
      s &= vbCrLf & "Queue of String items (reported length " &
          CStr(queueString.Count) & "):"
      For i As Integer = 1 To queueString.Count
        s &= vbCrLf & queueString.Dequeue()
      Next i
    End Sub

See also

Generic Procedures in Visual Basic

A generic procedure, also called a generic method, is a procedure defined with at least one type parameter. This allows the calling code to tailor the data types to its requirements each time it calls the procedure.

A procedure is not generic simply by virtue of being defined inside a generic class or a generic structure. To be generic, the procedure must take at least one type parameter, in addition to any normal parameters it might take. A generic class or structure can contain nongeneric procedures, and a nongeneric class, structure, or module can contain generic procedures.

A generic procedure can use its type parameters in its normal parameter list, in its return type if it has one, and in its procedure code.

Type Inference

You can call a generic procedure without supplying any type arguments at all. If you call it this way, the compiler attempts to determine the appropriate data types to pass to the procedure's type arguments. This is called type inference. The following code shows a call in which the compiler infers that it should pass type String to the type parameter t.

Public Sub testSub(Of t)(ByVal arg As t)
End Sub
Public Sub callTestSub()
    testSub("Use this string")
End Sub

If the compiler cannot infer the type arguments from the context of your call, it reports an error. One possible cause of such an error is an array rank mismatch. For example, suppose you define a normal parameter as an array of a type parameter. If you call the generic procedure supplying an array of a different rank (number of dimensions), the mismatch causes type inference to fail. The following code shows a call in which a two-dimensional array is passed to a procedure that expects a one-dimensional array.

Public Sub demoSub(Of t)(ByVal arg() As t)
End Sub

Public Sub callDemoSub()
    Dim twoDimensions(,) As Integer
End Sub

You can invoke type inference only by omitting all the type arguments. If you supply one type argument, you must supply them all.

Type inference is supported only for generic procedures. You cannot invoke type inference on generic classes, structures, interfaces, or delegates.



The following example defines a generic Function procedure to find a particular element in an array. It defines one type parameter and uses it to construct the two parameters in the parameter list.


Public Function findElement(Of T As IComparable) (
        ByVal searchArray As T(), ByVal searchValue As T) As Integer

    If searchArray.GetLength(0) > 0 Then
        For i As Integer = 0 To searchArray.GetUpperBound(0)
            If searchArray(i).CompareTo(searchValue) = 0 Then Return i
        Next i
    End If

    Return -1
End Function


The preceding example requires the ability to compare searchValue against each element of searchArray. To guarantee this ability, it constrains the type parameter T to implement the IComparable<T> interface. The code uses the CompareTo method instead of the = operator, because there is no guarantee that a type argument supplied for T supports the = operator.

You can test the findElement procedure with the following code.

Public Sub tryFindElement()
    Dim stringArray() As String = {"abc", "def", "xyz"}
    Dim stringSearch As String = "abc"
    Dim integerArray() As Integer = {7, 8, 9}
    Dim integerSearch As Integer = 8
    Dim dateArray() As Date = {#4/17/1969#, #9/20/1998#, #5/31/2004#}
    Dim dateSearch As Date = Microsoft.VisualBasic.DateAndTime.Today
    MsgBox(CStr(findElement(Of String)(stringArray, stringSearch)))
    MsgBox(CStr(findElement(Of Integer)(integerArray, integerSearch)))
    MsgBox(CStr(findElement(Of Date)(dateArray, dateSearch)))
End Sub

The preceding calls to MsgBox display "0", "1", and "-1" respectively.

See also




ID: 200900019 Last Updated: 19/9/2020 Revision: 0 Ref:



  1. Active Server Pages,  ,
  2. ASP Overview,  ,
  3. ASP Best Practices,  ,
  4. ASP Built-in Objects,  ,
  5. Response Object,  ,
  6. Request Object,  ,
  7. Server Object (IIS),  ,
  8. Application Object (IIS),  ,
  9. Session Object (IIS),  ,
  10. ASPError Object,  ,
  11. ObjectContext Object (IIS),  ,
  12. Debugging Global.asa Files,  ,
  13. How to: Debug Global.asa files,  ,
  14. Calling COM Components from ASP Pages,  ,
  15. IIS ASP Scripting Reference,  ,
  16. ASP Keywords,  ,
  17. Creating Simple ASP Pages,  ,
  18. Including Files in ASP Applications,  ,
  19. ASP Overview,  ,
  20. FileSystemObject Object,  ,
  21.,  , ADO Object Model
  22. ADO Fundamentals,  ,

Home 5






Hobbies 8


Chinese 1097

English 337

Reference 67


Hardware 151


Application 198

Digitization 25

Latex 9

Manim 121

Numeric 19


Web 283

Unicode 494


CSS 58


OS 389

DeskTop 7

Python 19



Formulas 8

Algebra 25

Number Theory 206

Trigonometry 18

Geometry 21

Calculus 67

Complex Analysis 21


Tables 8


Mechanics 1

Rigid Bodies

Statics 92

Dynamics 37

Fluid 5

Fluid Kinematics 5


Process Control 1

Acoustics 19

FiniteElement 2


Electric 27

Biology 1

Geography 1

Copyright © 2000-2020 Sideway . All rights reserved Disclaimers last modified on 06 September 2019