- April 20, 2015
Generics provide a way for developers to define subroutines, functions, fields, properties as well as classes, structures, interfaces and even delegates in such a way that the parameters are not of any particular type. In a sense the constructs are defined in a generic approach.
The .NET Framework contains the following namespaces:System.Collections, System.Collections.Generic. The latter mimics very much the features of the former.
System.Collections namespace (nongeneric)
ICollection | (size, enumeration, thread safety) | derives from IEnumerable |
IComparer | Allows two objects to be compared | |
IDictionary | Collection object to represent its contents using name/value pairs | derives from ICollection, IEnumerable |
IDictionaryEnumerator | Enumerates the contents of a type supporting IDictionary | derives from IEnumerator |
IEnumerable | Returns IEnumerator interface for a collection | |
IEnumerator | Enables for each style iteration of items in collection | |
IList | Provides add, remove and index items in a list of objects | derives from ICollection, IEnumerable |
Public Interface ICollection
Inherits IEnumerable
Sub CopyTo(ByVal array As Array, ByVal index As Integer)
ReadOnly Property Count() As Integer
ReadOnly Property IsSynchronized() As Boolean
ReadOnly Property SyncRoot() As Object
End Interface
Public Interface IDictionary
Inherits ICollection, IEnumerable
Sub Add(ByVal key As Object, ByVal value As Object)
Sub Clear()
Function Contains(ByVal key As Object) As Boolean
Function GetEnumerator() As IDictionaryEnumerator
Sub Remove(ByVal key As Object)
ReadOnly Property IsFixedSize() As Boolean
ReadOnly Property IsReadOnly() As Boolean
Property Item(ByVal key As Object) As Object
ReadOnly Property Keys() As ICollection
ReadOnly Property Values() As ICollection
End Interface
IList provides the ability to insert, remove and index items
Public Interface IList
Inherits ICollection, IEnumerable
Function Add(ByVal value As Object) As Integer
Sub Clear()
Function Contains(ByVal value As Object) As Boolean
Function IndexOf(ByVal value As Object) As Integer
Sub Insert(ByVal index As Integer, ByVal value As Object)
Sub Remove(ByVal value As Object)
Sub RemoveAt(ByVal index As Integer)
ReadOnly Property IsFixedSize() As Boolean
ReadOnly Property IsReadOnly() As Boolean
Property Item(ByVal index As Integer) As Object
End Interface
ArrayList | dynamically sized Dim personList as New ArrayList() personList.AddRange(New Person(){New Person(“dave”), New Person(“tom”)} | IList ICollection IEnumerable ICloneable |
Hashtable | collection whereby each item is represented by a numerical key | IDictionary ICollection IEnumerable ICloneable |
Queue | first in – first out queue with members Dequeue() (removes object at the top of queue), Enqueue() (adds object to end of queue), Peek() (returns object at the beginning of queue without removing it) | ICollection ICloneable IEnumerable |
SortedList | similar to dictionary however items can be accessed by ordinal position | IDictionary ICollection IEnumerable ICloneable |
Stack | last in – first out queue using push, pop and peek | ICollection ICloneable IEnumerable |
Boxing/Unboxing is a term that is used when a value type variable is stored in a reference type structure. This occurs with all nongeneric types as they operate of the System.Objects type.
For example:
Dim ar as New ArrayList()
ar.Add(123) ‘boxing occurs
Dim i as Integer = CType(ar(0), Integer) ‘unboxing occurs
<p$1$2$3$4$5$6>
Using a generic collection:
Dim ar as New List(Of Integer)
ar.Add(10) ‘no boxing
Dim i as Integer = ar(0) ‘no unboxing
The following is a list of interfaces within the System.Collections.Generic namespace: ICollections(Of T), IComparer(Of T), IDictionary(Of K, V), IEnumerable(Of T), IEnumerator(Of T), and IList(Of T). There respective classes are as follows:
Collection(Of T) | generic collection | |
Comparer(Of T) | compares two generic objects | |
Dictionary(Of K, V) | name/value pairs | |
List(Of T) | dynamically resizable | |
Queue(Of T) | FIFO collection | |
SortedDictionary(Of K, V) | sorted set of name/value pairs | |
Stack(Of T) | LIFO collection | |
LinkedList(Of T) | doubly linked list | |
ReadOnlyCollection(Of T) | readonly set of items |
Public Function Test(Of T)(ByRef o1 as T, ByRef o2 as T) as T
‘do something
End Function
<p$1$2$3$4$5$6>
It is possible to establish constraints with respect to the type of T. The following is a complete list of the types of constraints:
Of T as Structure > the type parameter must be a value type (ie. structure)
Of T as Class > the type parameter must be a reference type (i.e. classes)
Of T as New > the type parameter must have a default constructor
Of T as NameOf BaseClass > the type parameter must be derived from the class specified by NameOfBaseClass
Of T as NameOfInterface > the type parameter must implement the interface specified by NameOfInterface
’new items must have a default constructor
Public Class TestClass(Of T as New)
‘stuff here
End Class
<p$1$2$3$4$5$6>
The term generic can apply to Interfaces as well. In any case the interface will define the contract that the implementing class must adhere to. When implementing a generic interface the supporting type specifies the placeholder type:
Public Interface IMyInterface(Of T) Function Add(ByVal x as T, ByVal y as T) as T End Interface
Public Class MyClass Implements IMyInterface(Of Integer)
Public Function Add(ByVal x as Integer, ByVal y as Integer) as Integer Return x + y End Function
By all means utilize the generic collection namespace over the system.collection nongeneric namespace. In addition to improved performance(avoiding boxing/unboxing) your code will avoid type-safety issues of earlier releases of .NET.