Dec

10

Generic Collection Base For Generic List (A Very Generic Blog)

Written by Duncan White

Public Class ItemCollection(Of T)
    Implements IList(Of T)

#Region "Declarations"
    Private _ItemList As New List(Of T)
#End Region

#Region "Properties: (IList(Of T))"
    Public ReadOnly Property Count() As Integer Implements System.Collections.Generic.ICollection(Of T).Count
        Get
            Return _ItemList.Count
        End Get
    End Property

    Public ReadOnly Property IsReadOnly() As Boolean Implements System.Collections.Generic.ICollection(Of T).IsReadOnly
        Get
            Return False
        End Get
    End Property

    Default Public Property Item(ByVal index As Integer) As T Implements System.Collections.Generic.IList(Of T).Item
        Get
            Return _ItemList(index)
        End Get
        Set(ByVal value As T)
            _ItemList(index) = value
        End Set
    End Property
#End Region

#Region "Public Methods: (IList(Of T))"
    Public Sub Add(ByVal item As T) Implements System.Collections.Generic.ICollection(Of T).Add
        _ItemList.Add(item)
    End Sub

    Public Sub Clear() Implements System.Collections.Generic.ICollection(Of T).Clear
        _ItemList.Clear()
    End Sub

    Public Function Contains(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Contains
        Return _ItemList.Contains(item)
    End Function

    Public Sub CopyTo(ByVal array() As T, ByVal arrayIndex As Integer) Implements System.Collections.Generic.ICollection(Of T).CopyTo
        _ItemList.CopyTo(array, arrayIndex)
    End Sub

    Public Function Remove(ByVal item As T) As Boolean Implements System.Collections.Generic.ICollection(Of T).Remove
        _ItemList.Remove(item)
    End Function

    Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
        Return New ItemEnumerator(Me)
    End Function

    Public Function IndexOf(ByVal item As T) As Integer Implements System.Collections.Generic.IList(Of T).IndexOf
        Return _ItemList.IndexOf(item)
    End Function

    Public Sub Insert(ByVal index As Integer, ByVal item As T) Implements System.Collections.Generic.IList(Of T).Insert
        _ItemList.Insert(index, item)
    End Sub

    Public Sub RemoveAt(ByVal index As Integer) Implements System.Collections.Generic.IList(Of T).RemoveAt
        _ItemList.RemoveAt(index)
    End Sub

    Public Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        Return New ItemEnumerator(Me)
    End Function
#End Region

#Region "Internal Class"
    Private Class ItemEnumerator
        Implements IEnumerator(Of T)

        Private CollectionBase As ItemCollection(Of T)
        Private Index As Integer

        Public Sub New(ByVal Base As ItemCollection(Of T))
            CollectionBase = Base
            Index = -1
        End Sub

        Public Function MoveNext() As Boolean Implements System.Collections.IEnumerator.MoveNext
            Index += 1

            Return Index < (CollectionBase._ItemList.Count)
        End Function

        Public Sub Reset() Implements System.Collections.IEnumerator.Reset
            Index = -1
        End Sub

        Public ReadOnly Property Current() As T Implements System.Collections.Generic.IEnumerator(Of T).Current
            Get
                Return CollectionBase._ItemList(Index)
            End Get
        End Property
        Public ReadOnly Property Current1() As Object Implements System.Collections.IEnumerator.Current
            Get
                Return CollectionBase._ItemList(Index)
            End Get
        End Property

        Private disposedValue As Boolean = False        ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: free other state (managed objects).
                End If

                ' TODO: free your own state (unmanaged objects).
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub

#Region " IDisposable Support "
        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class
#End Region

End Class

Now that you have finished scrolling through all that “sassy” looking code (There you go John), you may be asking yourself why in the world would I want to use a generic collection of generic objects? Quite simple, after copying the class you can reduce your collection writing, and standardize your list between multiple routines. The ItemCollection(Of T) is a one size fits all collection wrapper. For example, you are writing an application that needs to return a list, or even a nested list of objects that you want to enumerate through. This class will allow for that. Like in the following example:

Public Shared Function GetInventory() as ItemCollection(Of InventoryItem)
 Dim InventoryItems as DataTable = GetAllInventory()
 Dim Inventory as New ItemCollection(Of InventoryItem)

 For Each Item In InventoryItems.Rows
   Dim InventoryItem As New InventoryItem
   Dim Vendors as ItemCollection(Of Vendors) = GetVendors(InventoryID)
   Dim Assemblies as ItemCollection(Of InventoryItem) = GetAssemblies(InventoryID)
   Dim AlternateInventory as ItemCollection(Of InventoryItem) = GetAltInventory(InventoryID) 

   With InventoryItem
      .InventoryID = Item("InventoryID")
      .PartNumber = Item("PartNumber")
      .Description = Item("Description")
      .Vendors = Vendors
      .Assemblies = Assemblies
      .AlternateInventory = AlternateInventory
   End With

   Inventory.Add(InventoryItem)
  Next
  Return Inventory
End Sub

Private Sub IterateInventoryVendors(Inventory As ItemCollection(Of Inventory))
  For Each Vendor as Vendor In Inventory(0).Vendors
   Console.WriteLine(Vendor.Name)
  Next
End Sub

Leave a Reply