1. Technology


Generics in Action


The easiest way to start learning about generics is to use one of the generic datatypes that are in VB.NET. Starting with the basics, the thing to look for that tells you that you're dealing with generic types is the Of keyword. It can be present in a lot of statements. Some examples:

In a Class statement:

Public Class myClass(Of T)
   Dim myVal As T
End Class

In a Structure statement:

Public Structure myStruct(Of T)
   Dim myVal As T
End Structure

In a Sub:

Public Sub callTestSub()
   testSub(Of String)("A String")
   testSub(Of Integer)(5)
End Sub

Public Sub testSub(Of T)(ByVal arg As T)
   Dim a As T
   a = arg
End Sub

You can also use generics in Delegates, Functions, and Interfaces.

The examples above all use the variable T as the generic placeholder. The use of T isn't required (the last example here doesn't use it), but it's traditional and you see it a lot in Microsoft documentation. You could use another variable name.

The easiest way to introduce generics in an actual code example is to use one of the generic types that have been added to the System.Collections.Generic namespace. These are types that accept generic placeholders (like Of T) as arguments. It's worth checking out this namespace in the Visual Studio Object Browser.

Click Here to display the illustration
Click the Back button on your browser to return

The traditional example, used by Microsoft in their seminars, is to start with a Framework 1.X ArrayList object for comparison. The following code shows that you can add any datatype to the ArrayList.

Dim myArrayList As ArrayList = New ArrayList()
myArrayList.Add("Ain't ArrayList Great!")

This works pretty well ... except when it comes time to do something with the ArrayList.

Dim total As Integer = 0
Dim val As Integer
For Each val In myArrayList
   total = total + val

As the illustration below shows, strings and integers don't mix when you try to add them.

Click Here to display the illustration
Click the Back button on your browser to return

This problem is the heart of what is called Type Safety. The code compiles perfectly ... no problem. But it crashes when the program runs. If the code is reading data from a file, it might not crash for years. (It will wait until you're on vacation 5000 miles away and then crash!) The goal is to find potential problems at compile time when it's easy to fix them. Generics take huge strides toward this goal.

Dim myGenericList As List(Of Integer) = New List(Of Integer)
myGenericList.Add("But Generic List is Better!")

As the illustration below shows, Intellisense displays an error and the project won't compile with this potential error. Trust me, it's a lot better than having the program crash when you're on vacation. (Keep in mind that Option Strict On must be specified, however.)

Click Here to display the illustration
Click the Back button on your browser to return

There are more reasons to use generics. Another is performance!

The reason ArrayList can hold any datatype is that data is boxed when it's saved in an ArrayList and unboxed when it's retrieved again. If you read about boxing at MSDN, you will see several pages about converting between value types and reference types and whether the data is stored on the heap or the stack. The bottom line is that there is a very slow conversion from and to the Object type - the only type that anything can be converted into.

With generics, the compiler checks for type safety, so no boxing or unboxing is necessary. Let's see what this means in code.

To measure our performance, we're going to use the System.Diagnostics.Stopwatch object. And as before, it's the Framework 1.X ArrayList object in one corner and the new challenger, Framework 2.0 List in the other. Let's have a clean fight and come out looping.

Only some of the code is reproduced here to keep things as compact as possible. So copying and pasting this code exactly won't work. The entire solution can be downloaded at the end of the article.

The code below does these things:

  • Sets the Stopwatch
  • Stuffs 10,000,000 integers into an ArrayList or List
  • Gets them again
  • Stops the Stopwatch
  • Displays the result

The code for ArrayList is shown. The code for generic List is the same with myGenericList substituted for myArrayList.

Dim myArrayList As ArrayList = New ArrayList()
' Dim myGenericList As List(Of Integer) = New List(Of Integer)
For i = 0 To 10000000

For Each value In myArrayList
   getit = value

TextBox1.Text = CStr(stopWatch.Elapsed().TotalSeconds)

On my PC, the results of the test are dramatic. See below!

Click Here to display the illustration
Click the Back button on your browser to return

You can define your own generic classes too. Returning to the first example, the only thing generics did for us was to let VB.NET flag the possible conflict between strings and integers so we wouldn't take the chance of a runtime exception. But what if we needed both strings and integers? The illustration below shows the same example, but this one doesn't crash. The very simple class in the example serves mainly to inherit from the base List class, although there's an example of a method in it as well. It's there mainly to demonstrate how a method in a generic class works.

Click Here to display the illustration
Click the Back button on your browser to return

In general, if you used an Object type in your program before, you can use generics now and get better, faster results.

The generic List object is also useful because it has some very powerful methods like ForEach, FindAll, and Sort defined for it. To learn about those, you might want to continue on with the next article in this series: The Useful Generic List in VB.NET.

To download the source code for this article, click here.

  1. About.com
  2. Technology
  3. Visual Basic

©2014 About.com. All rights reserved.