Isaiah's Blog

A vbCity Leader's journal

This blog hosted by:
http://blogs.vbcity.com      
  Home :: Syndication  :: Login

OctNovember 2008Dec
SMTWTFS
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

Articles

Archives

Topics

Image Galleries

Blogs I Read

Summary: Provides an overview of generics, constraints and their implementation.

 

Generics in Visual Basics 2005 make it possible to re-use code and still have strong typing.  With Visual Basics 2003 a different collection had to be defined for each data-type causing repetition of code. Generics allows for classes and methods to facilitate unrelated types. A major benefit of Generics is that one collection can be created to handle all data-types needed, thus cutting the amount of code needed.

 

Using Object as the item for the collection is another way that one collection can handle all data-types needed. However, with the use of Object the performance would be adversely affected because the types would require casting and type validation. Whereas, with the use of Generics the collection is strongly typed for all data-types; meaning that there is automatic type validation and other processes are avoided that would affect performance. 

 

Defining Generic Types

 

A generic type is considered to be a complete generic class. When defining a generic class the Of keyword followed by a character(s) is added to class definition.

 

This is a definition of a regular class:


Public Class DemoClass

    ' Some methods and types here!

End Class

 

And now this is a definition of a generic class:


Public Class DemoClass(Of t)

    ' Some methods and types here!

End Class

 

Notice the difference between the regular class definition and the generic class definition. The generic class has the keyword Of followed by a t in parentheses at the end of the declaration line. The Of keyword is telling the compiler that there will be a type named “t” that will be filled in later. That type is defined by whatever is passed to it, when it is implemented. The character(s) that follows the Of keyword are known as a generic type parameter. Any combination of letters can be used, not just a single letter.  “t” would be considered the generic parameter in this case.

 

Using Generic Type Parameters

 

The use of generic types within methods allows the class to contain more flexible methods. The benefit of using these types within methods can clearly be seen through a strongly typed collection example.

 

Without the use of generics a simple add method within a collection would look like

 

Public Class DemoClass

    Inherits System.Collections.CollectionBase

 

    Public Function Add(ByVal value As Person) As Int32

        Me.InnerList.Add(value)

    End Function

End Class

 

However, with generics the collection is able to handle any type passed.

 

 Public Class GenericCollection(Of t)

    Inherits System.Collections.CollectionBase

   

    Public Function Add(ByVal value As t) As Int32

        Me.InnerList.Add(value)

    End Function

End Class

 

The amount of coding is cut due to the fact that one strongly typed collection can be created to handle all types needed. In the code example above the generic parameter is used as the type of the parameter for the Add function.

 

When defining the class for use a type must be passed to define the generic parameter, for that instance of the class.

 

Public Class DemoClass

    Public Sub RandomMethod()

        Dim gc As GenericCollection(Of Person)

    End Sub

End Class

 

Notice that the Person object has been used for the generic parameter in this case. In theory the code above creates a new instance of the GenericCollection class and passes the Person object as the generic parameter. What this means is that this instance of the GenericCollection is strongly typed for a Person object.

Creating Generic Methods

 

Creating generic methods is similar to the creation of a regular method.

This is a definition of a regular method.


Public Class DemoClass

    Public Sub RegularMethod()

        ' Some code goes here!

    End Sub

End Class


This is a definition of a generic method.

Public Class DemoClass

    Public Sub GenericMethod(Of t)()

        ' Some code goes here!

    End Sub

End Class

 

Generic methods can used to reduce the amount of code needed to complete several similar tasks. For example consider obtaining data from a database. One generic method can be written to handle all type within that database.

 

Public Function GetValues(Of t)(ByVal sql As String) As List(Of t)

    Dim cmd As New OleDbCommand(sql, connection)

    Dim reader As OleDbDataReader = cmd.ExecuteReader()

    Dim list As New List(Of t)

 

    While reader.Read()

        list.Add(CType(reader(0), t))

    End While

 

    Return list

End Function

 

Why use List(Of t) instead of CollectionBase?

 

When creating a new collection class List(Of t) should be used as the base class over CollectionBase. This is the case because CollectionBase is a non-generic class, and there is no efficient way to switch between non-generic and generic code. List(Of t) provides the full functionality of any give collection in generic form.

 

What if I want to limit generic types?

 

In several cases the generic type parameter needs to be limited to a specific type. Generic types need to be limited in these cases to ensure that the particular type can perform the task needed. These types are limited through the implementation of constraints. Considering a generic collection that contains a sort method, that generic type would have to be limited to types that implement the IComparable interface.


Public Class GenericCollection(Of t As IComparable(Of t))

    Inherits System.Collections.Generic.List(Of t)

    Public Sub New()

        ' Initialize a new instance of this object.

        MyBase.New()

    End Sub

End Class

 

Notice when the generic type is defined the constraint is also put into place. The constraint is defined by the use of the As keyword directly after the generic type parameter. It is important that the same character(s) be used in defining both the generic type parameter and the generic constraint.

 

IComparable is an interface that is implemented upon types that can be sorted. This interface defines a general method that tells the application how types should be compared. All collections can be sorted by a value within that collection. Notice that the code below does not implement the IComparable interface.

 

Public Class Person

    Private _firstName As String

    Private _lastName As String

 

    Public Property FirstName() As String

        Get

            Return _firstName

        End Get

        Set(ByVal value As String)

            _firstName = value

        End Set

    End Property

 

    Public Property LastName() As String

        Get

            Return _lastName

        End Get

        Set(ByVal value As String)

            _lastName = value

        End Set

    End Property

End Class

 

When the Person object, whose code is above, is used as the generic type for the GenericCollection class an error occurs.

 

Public Class DeomClass

    Public Sub DemoMethod()

        Dim gc As New GenericCollection(Of Person)

    End Sub

End Class

The error states that the Person object does not implement the IComparable interface. IComparable is used as a constraint to ensure that the type can be sorted. To correct the error simply implement the IComparable interface.

 

Public Class Person

    Implements IComparable(Of Person)

 

    ' The rest of the code for the object.

 

    Public Function CompareTo(ByVal other As Person) As Integer Implements System.IComparable(Of Person).CompareTo

 

    End Function

End Class

 

What if I need multiple constraints?

 

In some cases generic types need to be constrained by more than one constraint. Multiple constraints are defined just like single constraints with a small exception.

 

Public Class GenericCollection(Of t As {IComparable(Of t), New})

    Inherits System.Collections.Generic.List(Of t)

    Public Sub New()

        ' Initialize a new instance of this object.

        MyBase.New()

    End Sub

End Class

 

Notice that when defining multiple constraints they are enclosed in { } and separated by a comma.

 

Special Constraints

 

There are a few special constraints such as classes and new. These constraints are rather important to use because it ensures that the generic parameter has the capability to accomplish the task necessary. For instance when using a generic parameter that needs to be initialized, the constraint new needs to be used.

 

Public Class DemoClass(Of t As New)

    Public Function GetItem() As t

        Dim newType As New t

 

        ' Some more code here.

 

        Return newType

    End Function

End Class

 

The code above is used just to illustrate a purpose, and has no real functionality as it is. New is used as a constraint to ensure that the generic parameter has a default constructor to be called upon. Classes are used as constraints to check if the type inherits from that particular class. The use of classes as a constraint is a good idea because it ensures that the type will be able to perform the functions within the class.

 

Generics and constraints reduce the amount of work that the program used to have to do. In the past a programmer had to create several collections that all served the same purpose and perhaps had to spend a great deal of time debugging that code. Now with generics that headache has become a thing of the past.

posted on Tuesday, June 10, 2008 6:42 PM

Feedback

No comments posted yet.

Post Feedback

Title:
Name:
Url:
Comments: 
Protected by Clearscreen.SharpHIPEnter the code you see: