New Features in VB.NET — Generics
by Wei-Meng Lee05/25/2004
One of the new features in .NET Framework 2.0 is the support of Generics in the Intermediate Language (IL). As such, languages such as C# and VB.NET now support this new feature. You've heard a lot about Generics in C#, but seldom hear people talk about it in VB.NET. (Note that Generics is a feature of the IL, and not specific to C# alone). And so in this article I'm going to introduce Generics to the VB.NET programmer.
Understanding Generics
To understand how Generics work, let's consider an example. Suppose you need to implement a Stack class. A stack is a Last-In-First-Out (LIFO) data structure that allows you to push items into the stack, as well as pop items out of a stack. One possible implementation is:
Public Class MyStack
Private element() As Integer ' create a dynamic array
Private pointer As Integer
Public Sub New(ByVal size As Integer)
ReDim element(size - 1)
pointer = 0
End Sub
Public Sub Push(ByVal item As Integer)
If pointer > UBound(element) Then
Throw New Exception("Stack is full.")
End If
element(pointer) = item
pointer += 1
End Sub
Public Function Pop() As Integer
pointer -= 1
If pointer < 0 Then
Throw New Exception("Stack is empty.")
End If
Return element(pointer)
End Function
End Class
As you can see, this Stack implementation accepts stack items of the Integer data type. If you wish to use this implementation for another data type, say String, you need to create another identical class but instead use the String type. Obviously this is not a very flexible way of writing your class definition.
One common way of solving this problem is to use the Object data type so that the compiler will use late-binding (note the changes in bold):
Public Class MyStack
Private element() As Object ' uses Object for late-binding
Private pointer As Integer
Public Sub New(ByVal size As Integer)
ReDim element(size - 1)
pointer = 0
End Sub
Public Sub Push(ByVal item As Object)
If pointer > UBound(element) Then
Throw New Exception("Stack is full.")
End If
element(pointer) = item
pointer += 1
End Sub
Public Function Pop() As Object
pointer -= 1
If pointer < 0 Then
Throw New Exception("Stack is empty.")
End If
Return element(pointer)
End Function
End Class
One problem with this approach is that when you use the Stack class, you may inadvertently "push" in the wrong data type, as shown in the following code in bold:
Dim stackC As New MyStack(2)
stackC.Push(5)
stackC.Push("A")
Dim val1, val2 As Integer
val1 = stackC.pop 'runtime error here
However, this mistake will only be detected during runtime when you try to pop out a String value and try to assign it to an Integer variable.
In VB.NET, a new type known as Generics is supported. Using Generics, you do not need to fix the data type of the items used by your Stack class. Instead, you use the new keyword Of, which identifies the data type parameter on a class, structure, interface, delegate, or procedure. To see the use of the Generics, let's rewrite the Stack class:
Public Class MyStack(Of itemType)
Private element() As itemType ' create a dynamic array
Private pointer As Integer
Public Sub New(ByVal size As Integer)
ReDim element(size - 1)
pointer = 0
End Sub
Public Sub Push(ByVal item As itemType)
If pointer > UBound(element) Then
Throw New Exception("Stack is full.")
End If
element(pointer) = item
pointer += 1
End Sub
Public Function Pop() As itemType
pointer -= 1
If pointer < 0 Then
Throw New Exception("Stack is empty.")
End If
Return element(pointer)
End Function
End Class
As highlighted in bold, I have used the name itemType as a placeholder for the eventual data type that I want to use for your class. That is, during the design stage of this class, I don't specify the data type that my Stack class will deal with.
If I want my Stack class to manipulate items of type Integer, I specify that during the instantiation stage:
Dim stackA As New MyStack(Of Integer)(2)
' the itemType will now be replaced by the Integer
stackA.Push(5)
stackA.Push(6)
stackA.Push("Some string...") ' compile-time error
MsgBox(stackA.pop)
MsgBox(stackA.pop)
MsgBox(stackA.pop)
The third Push() method will generate a compile-time error. This is because the compiler checks the data type used by my Stack class during compile time. This is one advantage of using Generics in VB.NET.
If I want to use the Stack class for String data types, I simply do this:
Dim stackB As New MyStack(Of String)(3)
stackB.Push("Generics")
stackB.Push("supports ")
stackB.Push("VB.NET ")
MsgBox(stackB.pop)
MsgBox(stackB.pop)
MsgBox(stackB.pop)
Advantages of Generics
Based on what I've discussed in the previous section, it's not difficult to see the following advantages of using Generics:
- Type Safety -- Generic types enforce type compliance at compile-time, and not run-time (as in the case of using Object). This reduces the chances of data-type conflict during run-time.
- Performance -- The data types to be used in a Generic class are determined at compile-time, hence there is no need to perform type casting during run-time, which is a computationally costly process.
- Code reuse -- Since you only need to write the class once and customize it to use with the various data types, there is a substantial amount of code-reuse.
Terms
Figure 1 shows the terms used in a Generic type:

Figure 1. Terms used in Generics.
Using Constraints in a Generic Type
You can further impose constraints on a Generic type. For example, if I want my Stack class to only manipulate objects of a certain type, say of type Employee, I can declare my Generic type as:
Public Class MyStack(Of itemType As Employee)
You can also specify multiple constraints in a Generic type. The syntax for specifying multiple constraints is {type1, type2, ..., typeN}. As an example, if I want the Stack class to manipulate objects of type Employee and also implement the Icompatable interface, I can declare my Generic type as:
Public Class MyStack(Of itemType As {Employee, IComparable})
To see the use of constraints in Generics, assume that I have the following class definitions:
Public Class Employee
Implements IComparable
Public employeeID As String
Public name As String
Public Function CompareTo(ByVal obj As Object) As Integer _
Implements System.IComparable.CompareTo
' add code here
End Function
End Class
Public Class Manager
Inherits Employee
...
End Class
Public Class Programmer
Inherits Employee
...
End Class
Then the following statements are valid:
Dim stackD As New MyStack(Of Programmer)(3)
Dim stackE As New MyStack(Of Employee)(3)
Dim stackF As New MyStack(Of Manager)(3)
Summary
Generics is an improved way to write your classes. And by doing so, your code is now much simpler to understand, more efficient, and most importantly, safer.
Wei-Meng Lee (weimenglee.blogspot.com) is a technologist and founder of Developer Learning Solutions, a technology company specializing in hands-on training of the latest Microsoft technologies.
Return to ONDotnet.com.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 6 of 6.
-
Very Nice way to start
2007-08-08 07:35:17 VinuTutorials [Reply | View]
Good article for beginners who streted using Generics...
-
Very Nice way to start
2007-08-08 07:34:24 VinuTutorials [Reply | View]
Good article for beginners who streted using Generics...
-
Some missing, but ver useful information
2006-06-30 08:16:59 mindcore [Reply | View]
Ver good article, however the author failed to point out one very important piece of information. Generics in VB.NET are very dangerous if you do not put Option Strict On at the beginning of your code or as your default in the configuration. VB.NET has a tendency to autocast if strict is not on. What does this mean? Well try the following with and without strict on:
Dim list as System.Collections.Generics.Ilist(Of Integer) = New System.Collections.Generics.Ilist(Of Integer)
Dim test1 As Integer = 1<br/>
Dim test2 As String = "2"
list.Add(test1)
list.Add(test2)
NOTE: Change test2's value to an "a" with option strict off and the code will still compile, but you will receive an InvalidCastException at list.Add(test2).
-
Great Introduction to Generics
2006-04-12 10:08:00 Jawwad.Alam [Reply | View]
Wow...Simply great introduction to generics.. and yes vb world will surely catch all good bits.
-
The comunity of fast food.
2006-04-04 05:52:44 DeeJayT [Reply | View]
I think VB comunity always whas a "comunity of fast food", it always want a quickly solution for everything, i think that Generics will be wronly used by VB comunity (or by de old VB programmers).
-
Nice article
2004-07-08 00:30:07 himraj13 [Reply | View]
well i didnt know that this can also b done vb.net. i thought this type of feature is not supported by vb.net but this guy has given me a very fine review of generics in vb.net. this artical has given me a new point of view to vb.net.
i really appreciate this artical as a golden piece of code.
thanks buddy!!!





