Full Version: Using Generics in VB.Net Part II
Dream.In.Code > Programming Tutorials > VB.NET Tutorials
PsychoCoder
Welcome to Part II of my tutorial series on Generics in VB.Net, as you recall, in my first tutorial I gave examples of how Generics improved code re-usability, efficiency and readability of code. I gave an overview of what Generics were and how they can be used. In this tutorial I will be discussing adding Constraints in your Generics classes.

What are Constraints? Adding a Constraint to your Generics class restricts or limits the possible types that the class will accept. With a Constraint you can ensure your collection only contains or accepts reference types. It also makes it possible to restrict your collection or class to only allow types that implement a certain interface, say IComparable(Of T) or IEnumerable(Of T). You can also specify more than one Constraint for a type, you do that like (Of T As {Automobile,IEnumerable}).

First lets create a class named Automobile that implements IComparable, then a couple smaller classes that inherit from Automobile

NOTE:A class that implements IComparable has to have a CompareTo Function that implements IComparable.CompareTo

CODE

Public Class Automobile : Implements IComparable

   'Lets add some variables & properties to our class
   Public _automobileID As Integer
   Public _color As System.Drawing.Color
   Public _numDoors As Integer
   Public _transType As String

   Public Property Color() As System.Drawing.Color
      Get
         Return _color
      End Get
      Set(ByVal value As System.Drawing.Color)
         _color = value
      End Set
   End Property

   Public Property NumberOfDoors() As Integer
      Get
         Return Integer.TryParse(_numDoors,New Integer)
      End Get
      Set(ByVal value As Integer)
         _numDoors = value
      End Set
   End Property

   Public Property Transmission() As String
      Get
         Return _transType
      End Get
      Set(ByVal value As Integer)
         _transType = value
      End Set
   End Property

   Public ReadOnly Property AutomobileID() As Integer
      Get
         Return _automobileID
      End Get
   End Property

   Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
      If Not (TypeOf obj Is Automobile) Then
          Throw New ArgumentException
      End If

      Dim Automobile2 As Automobile = CType(obj, Automobile)
      Dim cmpl As Integer = Me.AutomobileID.CompareTo(Automobile.AutomobileID)
      If Not (cmpl = 0) Then
         Return cmpl
      End If
      Return Me.AutomobileID.CompareTo(f2.AutomobileID)
   End Function
End Class

Public Class HotRod : Inherits Automobile
   'add your class code here
End Class

Public Class Jalopy : Inherits Automobile
   'add your class code here
End Class

Public Class Truck : Inherits Automobile
   'add your class code here
End Class


Now that we have our Automobile class, lets use this as a constraint in our TheStackClass class by restricting the types it can accept to the type Automobile We will add a 2 constraints on the original type parameter as Automobile and IComparable.

CODE

Public Class TheStackClass(Of type As {Automobile,IComparable})
   'declare the variables we need
   Private item() As type  'create a dynamic array
   private itemPointer As Integer  'Create a pointer to the item

   'instantiate the class and set its size
   Public Sub New(ByVal itemSize As Integer)
      'Redim the dynamic array upon instantiation
      ReDim item(itemSize - 1)
      'set the itemPointer to zero
      itemPointer = 0
   End Sub

   '"Push" or add an item to the stack
   Public Sub PushItem(Of Automobile)(ByVal i As type)
      'first make sure the stack isnt full
      If itemPointer > UBound(item) Then
         Throw New ArgumentOutOfRangeException("The stack is currently full. Please remove an item before attempting to add a new one")
      Else  'stack isnt full
         item(itemPointer) = i
         itemPointer +=1
      End If
   End Sub

   '"Pop" or remove an item from the stack
   Public Function PopItem() As type
      'decrement the itemPointer
      itemPointer -= 1
      'check to see if the stack is empty
      If itemPointer < 0 Then  'stack is currently empty
         Throw New ArgumentOutOfRangeException("The stack is currently empty.You cannot remove an item from an empty stack")
      End If
      'return the itemPointer value
      Return item(itemPointer)
   End Function
End Class


As you notice, in the original class it was Public Class TheStackClass(Of Type), but adding the constraint Public Class TheStackTrace(Of type {Automobile,IComparable}) we have added a constraint that the only types this will now accept are Automobile and IComparable.

Also, the PushItem method we added a Constraint to that as well, changing the definition to Public Sub PushItem(Of Automobile)(ByVal i As type), yes you can add Constraints to methods within the Generic Class as well.

If we tried to now call this class the way we did originally

CODE

Dim MyStack As New TheStackClass(Of String)(4)


THis would cause a compile time error, we now have to call it like this

CODE

Dim MyStack As New TheStackClass(Of HotRod)(3)
Dim MyStack As New TheStackClass(Of Jalopy)(4)
Dim MyStack As New TheStackClass(Of Truck)(2)
'and so on.....


Notice we use the Type HotRod, this is one of the classes we have that inherits the Automobile class. Using Constraints in your Generic Type is definitely an improved way of writing code, it also makes it more efficient, easier to read and type safe.

This is a high-level overview of adding a constraint to your Generic class, though there are many more things you can do with Generics, many more constraints you can work with, Generics in VB.Net do have many more limitations than its counterpart C#. Some of the limitations are:
  • Since Generics without constraints are viewed as System.Object types, you cannot access type members not available to System.Object
  • You cannot use arithmetic operations or nested class (though constraints can be added to soften this up a little)
  • You cannot access static members or nested classes without explicit casting (Ctype(obj,TheTypeYouWant))
  • You cannot use arithmetic operations unless your base class supports them (your base class is your constraint)
  • You cannot use Generics as type arguments

So that is adding Constraints to your Generics Class, if you have questions or comments you can send me a PM and I will answer them. Better yet, post your questions here and I can answer them for you, and anyone else who may have the same question. Thank you for reading.

Happy Coding!
wille45
I need help writing code without creating a form.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2009 Invision Power Services, Inc.