Collections


The Visual Basic collection classes basically hold items and don’t provide a lot of extra functionality. Other classes described later in this chapter provide more features.

The following sections describe the simple collection classes in Visual Basic: ArrayList, StringCollection, and NameValueCollection. They also describe strongly typed collections that you can build to make code that uses these classes a bit easier to debug and maintain.

ArrayList

The ArrayList class is a resizable array. You can add and remove items from any position in the list and it resizes itself accordingly. The following table describes some of the class’s more useful properties and methods.

Open table as spreadsheet

Property/Method

Purpose

Add

Adds an item at the end of the list.

AddRange

Adds the items in an object implementing the ICollection interface to the end of the list.

BinarySearch

Returns the index of an item in the list. The items must implement the IComparable interface, or you must provide the Sort method with an IComparer object.

Capacity

Gets or sets the number of items that the list can hold. For example, if you know that you will need to add 1000 items to the list, you may get better performance by setting Capacity to 1000 before starting, rather than letting the object grow incrementally as you add the items.

Clear

Removes all of the items from the list. The Capacity property remains unchanged, so the ArrayList keeps any space it has previously allocated to improve performance.

Contains

Returns True if a specified item is in the list.

CopyTo

Copies some or the entire list into a one-dimensional Array object.

Count

The number of items currently in the list. This is always less than or equal to Capacity.

GetRange

Returns an ArrayList containing the items in part of the list.

IndexOf

Returns the zero-based index of the first occurrence of a specified item in the list.

Insert

Adds an item at a particular position in the list.

InsertRange

Adds the items in an object implementing the ICollection interface to a particular position in the list.

Item

Returns the item at a particular position in the list.

LastIndexOf

Returns the zero-based index of the last occurrence of a specified item in the list.

Remove

Removes the first occurrence of a specified item from the list.

RemoveAt

Removes the item at the specified position in the list.

RemoveRange

Removes the items in the specified positions from the list.

Reverse

Reverses the order of the items in the list.

SetRange

Replaces the items in part of the list with new items taken from an ICollection object.

Sort

Sorts the items in the list. The items must implement the IComparable interface, or you must provide the Sort method with an IComparer object.

ToArray

Copies the list’s items into a one-dimensional array.

TrimToSize

Reduces the list’s allocated space so that it is just big enough to hold its items. This sets Capacity = Count.

The ToArray method can copy the items into an array of objects, an array of a specific type, or an Array object (holding objects). The following code demonstrates each of these. ToArray returns a generic array of Object even if the objects are some other data type such as strings, so the second method must use a DirectCast statement to convert the result into an array of strings, if Option Strict is On.

  ' Declare and initialize the ArrayList. Dim array_list As New ArrayList array_list.Add("Apple") array_list.Add("Banana") array_list.Add("Cherry") ... ' Array of objects. Dim obj_array() As Object obj_array = array_list.ToArray() ' Array of strings. Dim string_array() As String string_array = DirectCast(array_list.ToArray(GetType(String)), String()) ' Array object of objects. Dim astring_array As Array astring_array = array_list.ToArray()  

A single ArrayList object can hold objects of many different kinds. The following code creates an ArrayList and adds a string, Form object, integer, and Bitmap to it. It then loops through the items in the list and displays their types.

  Dim array_list As New ArrayList array_list.Add("What?") array_list.Add(Me) array_list.Add(1001) array_list.Add(New Bitmap(10, 10)) For Each obj As Object In array_list     Debug.WriteLine(obj.GetType.ToString) Next obj  

The following text shows the results:

  System.String UseArrayList.Form1 System.Int32 System.Drawing.Bitmap 

The value displayed for the second item depends on the name of the project (in this case, UseArrayList).

StringCollection

A StringCollection is similar to an ArrayList, except that it can hold only strings. Because it works only with strings, this class provides some extra type checking that the ArrayList does not. If your program tries to add an Employee object to a StringCollection, the collection raises an error.

To take advantage of this extra error checking, you should always use a StringCollection instead of an ArrayList if you are working with strings. Of course, if you need other features (such as the fast lookups provided by a Hashtable), you should use one of the classes described in the following sections.

Strongly Typed Collections

A strongly typed collection is a collection class built to work with a particular data type. An ArrayList can store objects of any data type. A StringCollection is strongly typed to work only with strings. That gives you extra error checking that makes finding and fixing programming mistakes easier. If the program tries to insert an IncidentReport object into a StringCollection, the collection immediately raises an error and the problem is relatively easy to find.

Similarly, you can define your own collection classes that are strongly typed. For example, you could make an OrderCollection class that holds Order items. If the program tries to add a Manager or Secretary object to it, the collection raises an error.

To build a strongly typed collection from scratch, create a new class that inherits from System .Collections.CollectionBase. Inheriting from this class automatically gives your class an ArrayList object named List. It also gives your class some inherited routines that do not depend on the type of object you want the collection to hold. For example, the RemoveAt method removes the object at a specific index in the list. It doesn’t care whether the collection holds Employee objects, bitmaps, or Pizzas, so the parent class CollectionBase can implement it for you.

Your class can implement other methods for adding and retrieving items in the collection. For example, it can implement the Add, Remove, and Item methods.

Fortunately, you don’t need to build these methods from scratch. You can simply delegate them to the inherited List object. For example, the Add method can simply call List.Add, as shown in the following code:

  ' Add an Employee. Public Sub Add(ByVal value As Employee)     List.Add(value) End Sub 

This code does nothing other than call the List object’s methods. The only magic here is that the EmployeeCollection class’s Add method takes a parameter of a particular type (Employee), whereas the List object’s Add method takes a generic Object as a parameter. It is the EmployeeCollection class’s insistence on Employee objects that makes the collection strongly typed.

The Add and Item methods are about the minimum useful feature set you can provide for a strongly typed collection class.

The following table lists the standard methods provided by a strongly typed collection class. The third column indicates whether the CollectionBase parent class automatically provides the method, or whether you must delegate the method to the List object.

Open table as spreadsheet

Method

Purpose

Provided By

Add

Adds an item to the collection

List

Capacity

Returns the amount of space in the collection

CollectionBase

Clear

Removes all items from the collection

CollectionBase

Contains

Returns True if the collection contains a particular item

List

CopyTo

Copies items from the collection into an array

List

Count

Returns the number of items in the collection

CollectionBase

IndexOf

Returns the index of an item

List

InnerList

Returns an ArrayList holding the collection’s objects

CollectionBase

Insert

Inserts an item at a specific position

List

Item

Returns the item at a specific position

List

List

Returns an IList holding the collection’s objects

CollectionBase

Remove

Removes an item

List

RemoveAt

Removes the item at a specific position

CollectionBase

You can also add other more specialized methods if they would be useful in your application. For example, you could add methods for working with object field values rather than with the objects themselves. You might make an overloaded version of the Item method that takes as parameters a first and last name and returns the corresponding Employee object if it is in the list. You could also modify the simple Add method shown previously so that it doesn’t allow duplicates. And, you could make an Add function that takes first and last names as parameters, creates a new Employee object using those names, and returns the new object.

The following code shows a complete EmployeeCollection class. Most of its methods are straightforward delegations to the List object. The most interesting method is the Item property. This method is implemented as a read-only property, so it can include the Default keyword (which is not allowed on functions). This keyword marks Item as the class’s default property and that allows a program to access it by providing an index to an object of the class as in emp_collection(3). Notice that the Item property procedure uses DirectCast to convert the generic Object stored in List into an Employee object.

  ' A strongly typed collection of Employees. Public Class EmployeeCollection     Inherits CollectionBase     ' Add an Employee.     Public Sub Add(ByVal value As Employee)         List.Add(value)     End Sub     ' Return True if the collection contains this employee.     Public Function Contains(ByVal value As Employee) As Boolean         Return List.Contains(value)     End Function     ' Return this Employee's index.     Public Function IndexOf(ByVal value As Employee) As Integer         Return List.IndexOf(value)     End Function     ' Insert a new Employee.     Public Sub Insert(ByVal index As Integer, ByVal value As Employee)         List.Insert(index, value)     End Sub     ' Return the Employee at this position.     Default Public ReadOnly Property Item(ByVal index As Integer) As Employee         Get             Return DirectCast(List.Item(index), Employee)         End Get     End Property     ' Remove an Employee.     Public Sub Remove(ByVal value As Employee)         List.Remove(value)     End Sub End Class  

An additional benefit that comes with inheriting from the CollectionBase class is For Each loop support. The following code shows how a program might use this EmployeeCollection class. It creates the collection and adds five Employee objects to the list. It then uses a For Each loop to display the Employees.

  Dim emp_list As New EmployeeCollection emp_list.Add(New Employee("Ann", "Anderson")) emp_list.Add(New Employee("Bart", "Baskerville")) emp_list.Add(New Employee("Candy", "Cant")) emp_list.Add(New Employee("Durk", "Distant")) emp_list.Add(New Employee("Edwina", "Evers")) For Each emp As Employee In emp_list     Debug.WriteLine(emp.ToString) Next emp 

Generics provide another method for building strongly typed collections. Refer to the section “Generics” later in this chapter for more information on generic collections. For more general information on generics, see Chapter 19.

Read-Only Strongly Typed Collections

The CollectionBase class enables you to build a strongly typed collection class that allows a program to store and retrieve values. In some cases, you might want a function to return a collection of objects that the calling program cannot modify. For example, suppose that your function returns a list of your company’s production locations. You don’t want the program to modify the list because it cannot change the locations. In this case, you can build a read-only strongly typed collection.

You can do this much as you build a strongly typed collection. Instead of deriving the new collection class from CollectionBase, however, derive it from the ReadOnlyCollectionBase class. Provide read-only Item methods, but do not provide any Add or Remove methods. The class itself can access its inherited InnerList object to add and remove items, but it must not give the program using your class access to that object.

Your program still needs a way to get objects into the collection, however. One method is to build the collection class in a separate library project and give it initialization methods declared with the Friend keyword. Other code in the library project could use those methods while the main program could not.

Another technique is to pass initialization data to the class’s constructor. Your code creates the collection and returns it to the main program. The main program cannot change the collection’s contents. It can create an instance of the collection of its own, but it cannot modify the one you built.

NameValueCollection

The NameValueCollection class is a collection that can hold more than one string value for a particular key (name). For example, you might use employee names as keys. The string values associated with a particular key could include extension, job title, employee ID, and so forth.

Of course, you could also store the same information by putting extension, job title, employee ID, and the other fields in an object or structure, and then storing the objects or structures in some sort of collection class such as an ArrayList. A NameValueCollection, however, is very useful if you don’t know ahead of time how many strings will be associated with each key.

The following table describes some of the NameValueCollection’s most useful properties and methods.

Open table as spreadsheet

Property/Method

Description

Add

Adds a new name/value pair to the collection. If the collection already holds an entry for the name, it adds the new value to that name’s values.

AllKeys

Returns a string array holding all of the key values.

Clear

Removes all names and values from the collection.

CopyTo

Copies items starting at a particular index into a one-dimensional Array object. This copies only the items (see the Item property) not the keys.

Count

Returns the number of key/value pairs in the collection.

Get

Gets the item for a particular index or name as a comma-separated list of values.

GetKey

Returns the key for a specific index.

GetValues

Returns a string array containing the values for a specific name or index.

HasKeys

Returns True if the collection contains any non-null keys.

Item

Gets or sets the item for a particular index or name as a comma-separated list of values.

Keys

Returns a collection containing the keys.

Remove

Removes a particular name and all of its values.

Set

Sets the item for a particular index or name as a comma-separated list of values.

The following code demonstrates some of these features. It creates a NameValueCollection and fills it with values. It associates the name Food with the values Sandwich, Salad, and Taco. It associates the name Dessert with the values Ice Cream, Pie, Cake, and Cookie. Next, the code loops through the collection’s keys. For each key, it displays the key’s name, uses the collection’s GetValues method to get an array containing the corresponding values, and then displays those values. The code then displays the values again in comma-separated lists. It again loops through the collection’s keys, this time using the

  Dim nvc As New NameValueCollection nvc.Add("Food", "Sandwich") nvc.Add("Food", "Salad") nvc.Add("Food", "Taco") nvc.Add("Dessert", "Ice Cream") nvc.Add("Dessert", "Pie") nvc.Add("Dessert", "Cake") nvc.Add("Dessert", "Cookie") Dim values() As String For Each key As String In nvc.Keys     Debug.WriteLine(key & ":")     values = nvc.GetValues(key)     For Each value As String In values         Debug.WriteLine("    " & value)     Next value Next key Debug.WriteLine("*****") For Each key As String In nvc.Keys     Debug.WriteLine(key & ": " & nvc.Item(key)) Next key  

The following text shows the result:

  Food:     Sandwich     Salad     Taco Dessert:     Ice Cream     Pie     Cake     Cookie ***** Food: Sandwich,Salad,Taco Dessert: Ice Cream,Pie,Cake,Cookie  

Note that there is no easy way to remove a particular value from a name. For example, it’s not trivial to remove the value Pie from the name Dessert. The following statement shows one method, although you would need to modify it slightly if you didn’t know whether the Pie entry was last in the list (so it might or might not be followed by a comma):

  nvc.Item("Dessert") = nvc.Item("Dessert").Replace("Pie,", "") 




Visual Basic 2005 with  .NET 3.0 Programmer's Reference
Visual Basic 2005 with .NET 3.0 Programmer's Reference
ISBN: 470137053
EAN: N/A
Year: 2007
Pages: 417

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net