You need to create a collection that can only contain one type of object and rejects attempts to add other data types.
Create a custom collection class by deriving from
System.Collections.CollectionBase
, and implement type-safe
Add
,
Remove
, and
Item
You could create a custom collection by implementing the IList , ICollection , and IEnumerable interfaces. However, .NET provides an easier option with the abstract CollectionBase class. Internally, the CollectionBase uses an ArrayList , which is exposed through the protected property List .
As an example, consider the simple Customer object shown here:
Public Class Customer Private _ID As Integer Private _FirstName As String Private _LastName As String Public Sub New(ByVal id As Integer, ByVal firstName As String, _ ByVal lastName As String) Me.ID = id Me.FirstName = firstName Me.LastName = lastName End Sub Public Property ID() As Integer Get Return Me._ID End Get Set(ByVal Value As Integer) Me._ID = Value End Set End Property Public Property FirstName() As String Get Return Me._FirstName End Get Set(ByVal Value As String) Me._FirstName = Value End Set End Property Public Property LastName() As String Get Return Me._LastName End Get Set(ByVal Value As String) Me._LastName = Value End Set End Property End Class
You can derive a type-safe CustomerCollection from CollectionBase . Then you add a strongly typed Add method and a default property named Item , which automatically casts the retrieved object to the correct type.
Public Class CustomerCollection Inherits System.Collections.CollectionBase Public Sub Add(ByVal item As Customer) Me.List.Add(item) End Sub Public Sub Remove(ByVal index As Integer) If index > Count - 1 Or index < 0 Then Throw New ArgumentOutOfRangeException( _ "No item at the specified index.") Else List.RemoveAt(index) End If End Sub Default Public Property Item(ByVal index As Integer) As Customer Get Return CType(Me.List.Item(index), Customer) End Get Set(ByVal Value As Customer) Me.List.Item(index) = Value End Set End Property End Class
Here's a simple test of the type-safe CustomerCollection :
Dim Customers As New CustomerCollection() ' This succeeds. Customers.Add(New Customer(1001, "Henry", "Bloge")) ' This fails at compile time. Customers.Add("This is a string")
One limitation of the CollectionBase approach is that you can only create nonkeyed collections (such as the ArrayList ). If you need to create a strongly typed dictionary collection, see recipe 3.17.
Incidentally, the .NET Framework includes one strongly typed collection class: the StringCollection class in the System.Collections.Specialized namespace, which only allows String objects.
You need to create a key-based collection that can only contain one type of object and rejects attempts to add other data types.
Create a custom dictionary collection class by deriving from
System.Collections.DictionaryBase
, and implement type-safe
Add
,
Remove
, and
Item
With a custom dictionary collection, you can place restrictions on the type of objects stored in the collection and on the type of object used to index items in the collection. Internally, the
DictionaryBase
object uses an ordinary
As an example, consider the simple Customer object shown in recipe 3.16. Using DictionaryBase , you can derive a type-safe CustomerDictionary that has a strongly typed Add method, which requires an integer key and only accepts Customer objects for insertion in a collection. You'll also implement a Remove method and a default property named Item , which automatically casts the retrieved object to the correct type.
Public Class CustomerDictionary Inherits System.Collections.DictionaryBase Public Sub Add(ByVal key As Integer, ByVal item As Customer) Me.Dictionary.Add(key, item) End Sub Public Sub Remove(ByVal key As Integer) Me.Dictionary.Remove(key) End Sub Default Public Property Item(ByVal key As Integer) As Customer Get Return CType(Me.Dictionary.Item(key), Customer) End Get Set(ByVal value As Customer) Me.Dictionary.Item(key) = value End Set End Property End Class
Here's a simple test of the type-safe CustomerDictionary :
Dim Customers As New CustomerDictionary() Dim CustomerA As New Customer(1001, "Henry", "Bloge") ' This succeeds. Customers.Add(CustomerA.ID, CustomerA) ' This fails because the object is not a Customer. Customers.Add(9024, "This is a string") ' This fails because the ID is not an integer. Customers.Add(CustomerA.FirstName, CustomerA)
Incidentally, the .NET Framework includes one strongly typed dictionary class: the StringDictionary class in the System.Collections.Specialized namespace, which only allows String objects.