Creating a Generic Class
When working with generics, choose classes that have a broad range of uses so that the time required to create the generic class will eventually pay you back in reduced development time. For example, collections are a type of class that you use with more than one datatype, and it's very likely that you'll use various forms of the same collection in multiple applications. Rather than build the collection from scratch each time, you can use generics to create a generic class prototype. To begin, you need to add the following Imports statement to your code:
Imports System.Collections.Generic
Once you add the Imports statement, you can create a generic class. The basic class will look familiar. You can use properties, functions, subs, fields, or anything else you'd normally use in a class, as shown in Listing 1.
Listing 1 Defining a Generic Class Type
Public Class MyGenericCollection(Of ItemType) ' Define a generic collection. Private Items As Collection(Of ItemType) ' Create a constructor. Public Sub New() Items = New Collection(Of ItemType) End Sub ' Returns the number of items in the collection. Public ReadOnly Property Count() As Integer Get Return Items.Count End Get End Property ' Get or set a specific item. Default Public Property Item(ByVal Index As Integer) As ItemType Get Return Items(Index) End Get Set(ByVal value As ItemType) Items(Index) = value End Set End Property ' Add a new item to the collection. Public Sub Add(ByVal Value As ItemType) Items.Add(Value) End Sub ' Remove an item from the collection. Public Sub RemoveAt(ByVal Item As Int32) Items.RemoveAt(Item) End Sub End Class
The class declaration should look familiar, but notice the (Of ItemType) entry. This entry is what differentiates a generic class from a standard class. Think of it as a placeholder for the type that you supply later when instantiating the class. When the .NET Framework sees this entry, it replaces it with the type supplied by the code using the class. Of course, you don't have to use ItemType in your classyou can call this generic class anything, just as you would a variable.
Because this is a collection class, the first task the code performs is to create a global variable to hold the collection. However, because you want to associate this collection with the generic datatype, you use the special (Of ItemType) again to tell the .NET Framework to create a specific collection. This is where the strong datatyping comes into play. Even though you don't know the datatype the collection will use, the .NET Framework will, and can create a collection of that type for you.
As with all classes, make sure that you include a constructor or New() sub. The constructor instantiates the collection in this case. Again, be sure to use the (Of ItemType) code to ensure that the code treats the generic data correctly.
You can use the collection any way that you would normally. For example, the Count property returns the number of items in the collection. In fact, this code doesn't look any different from the code you'd use in a standard class.
At times, you do need to work with the specific item type. The Item property demonstrates this principle. Notice that the property returns a value of ItemTypeyou don't know the datatype now, but the .NET Framework assigns it later. In fact, when I created this class, the IDE automatically created the correct Set() method for me. Notice that it also relies on ItemType. However, using generics doesn't prevent you from creating standard property entries. For example, the Item property is the default for this class, as specified by the Default keyword.
The class ends with two Subs. The first adds a new value to the collection based on ItemType; the second removes a value from the collection using the item number. A developer can't add the wrong datatype to the collection because the .NET Framework assigns and monitors the datatype. Consequently, you don't need to worry about someone providing the wrong type of data, although the class itself accepts generic input. Contrast this functionality with using an Object, where the developer using your class could provide any kind of input and you'd need to perform tests to ensure that it's the correct type.