17.2. Generics


The goal of generics is to create collections that are "type safe" but that can be reused at design time with any type. Thus, the designer of a generic List would like to be able to designate that the List class can hold any type of data, but a specific type will be declared when the List class is used, and the compiler will enforce the type safety.

17.2.1. Generic List Class

The classic problem with the Array type is its fixed size. If you do not know in advance how many objects an array will hold, you run the risk of declaring either too small an array (and running out of room) or too large an array (and wasting memory).

Suppose you create a program that gathers input from a web site. As you find objects (strings, books, values, etc.), you will add them to the array, but you have no idea how many objects you'll collect in any given session. The classic fixed-size array is not a good choice, as you can't predict how large an array you'll need.

The List class is like an array whose size is dynamically increased as required. Lists provide a number of useful methods and properties. Some of the most important are shown in Table 17-2.

Table 17-2. List methods and properties

Method or property

Purpose

Capacity

Property to get or set the number of elements the List can contain. This value is increased automatically if count exceeds capacity. You might set this value to reduce the number of reallocations, and you may call trim to reduce this value to the actual Count.

Count

Property to get the number of elements currently in the array.

Item

Gets or sets the element at the specified index. This is the indexer for the List class.a

Add

Public method to add an object to the List.

AddRange

Public method that adds the elements of an ICollection to the end of the List.

BinarySearch

Overloaded public method that uses a binary search to locate a specific element in a sorted List.

Clear

Removes all elements from the List.

Contains

Determines if an element is in the List.

CopyTo

Overloaded public method that copies a List to a one-dimensional array.

Exists

Determines if an element is in the List.

Find

Returns the first occurrence of the element in the List.

FindAll

Returns all the specified elements in the List.

GetEnumerator

Overloaded public method that returns an enumerator to iterate through a List.

GeTRange

Copies a range of elements to a new List.

IndexOf

Overloaded public method that returns the index of the first occurrence of a value.

Insert

Inserts an element into List.

InsertRange

Inserts the elements of a collection into the List.

LastIndexOf

Overloaded public method that returns the index of the last occurrence of a value in the List.

Remove

Removes the first occurrence of a specific object.

RemoveAt

Removes the element at the specified index.

RemoveRange

Removes a range of elements.

Reverse

Reverses the order of elements in the List.

Sort

Sorts the List.

ToArray

Copies the elements of the List to a new array.

TRimToSize

Sets the capacity to the actual number of elements in the List.

The idiom in the Framework Class Library is to provide an Item property for collection classes that is implemented as an indexer in Visual Basic 2005.


When you create a List, you do not define how many objects it will contain. Add to the List using the Add method, and the List takes care of its own internal bookkeeping, as illustrated in Example 17-4.

Example 17-4. Working with a List
 Imports System.Collections.Generic Module Module1    Sub Main(  )       Dim empList As New List(Of Employee)       Dim intList As New List(Of Integer)       For counter As Integer = 0 To 4          empList.Add(New Employee(counter + 100))          intList.Add(counter + 5)       Next       For Each val As Integer In intList          Console.Write(val.ToString(  ) + " ")       Next       Console.WriteLine(Environment.NewLine)       For Each emp As Employee In empList          Console.Write(emp.ToString(  ) + " ")       Next       Console.WriteLine(Environment.NewLine)       Console.WriteLine("empList.Capacity: {0}", empList.Capacity)    End Sub End Module Public Class Employee    Private employeeID As Integer    Public Sub New(ByVal theID As Integer)       Me.employeeID = theID    End Sub    Public Overrides Function ToString(  ) As String       Return employeeID.ToString(  )    End Function    Public Property EmpID(  ) As Integer       Get          Return employeeID       End Get       Set(ByVal value As Integer)          employeeID = value       End Set    End Property End Class Output: 0 5 10 15 20 100 101 102 103 104 empArray.Capacity: 8 

With an Array class, you define how many objects the array will hold. If you try to add more than that, the Array class will throw an exception. With a List, you do not declare how many objects the List will hold. The List has a property, Capacity, which is the number of elements the List is capable of storing:

 public int Capacity { get; set; } 

The default capacity is eight. When you add the ninth element, the capacity is automatically doubled to 16. If you change the For loop to:

 For counter As Integer = 0 To 8 

the output looks like this:

 5 6 7 8 9 10 11 12 13 100 101 102 103 104 105 106 107 108 empList.Capacity: 16 

You can manually set the capacity to any number equal to or greater than the count. If you set it to a number less than the count, the program will throw an exception of type ArgumentOutOfRangeException.

17.2.2. Implementing IComparable

Like all collections, the List implements the Sort method, which allows you to sort any objects that implement IComparable. In the next example, you'll modify the Employee object to implement IComparable:

 Public Class Employee    Implements IComparable(Of Employee) 

To implement the IComparable interface, the Employee object must provide a CompareTo method:

 Function CompareTo(ByVal rhs As Employee) As Integer _ Implements IComparable(Of IComparable.Employee).CompareTo    Return Me.employeeID.CompareTo(rhs.employeeID) End Function 

The CompareTo method has been implemented to take an Employee as a parameter. The current Employee object must compare itself to the parameter and return -1 if it is smaller than the parameter, 1 if it is greater than the parameter, and 0 if it is equal to the parameter.

It is up to Employee to determine what smaller than, greater than, and equal to actually mean. In the next example, you'll compare the EmployeeID (so that Employees can be sorted by EmployeeIDs.).


You are ready to sort the list of employees, empList. To see if the sort is working, you'll need to add integers and Employee instances to their respective lists with (pseudo)random values. To create the random values, you'll instantiate an object of class Random and call the Next method on the Random to return a pseudo-random number.

The Next method is overloaded; one version allows you to pass in an integer that represents the largest random number you want. In this case, you'll pass in the value 10 to generate a random number between 0 and 10:

 Random r = new Random(  ); r.Next(10); 

Example 17-5 creates and then sorts the two lists.

Example 17-5. Sorting generic Lists usng IComparable
 Imports System.Collections.Generic Module Module1    Sub Main(  )       Dim empList As New List(Of Employee)       Dim intList As New List(Of Integer)       Dim r As New Random(  )       For counter As Integer = 0 To 8          empList.Add(New Employee(r.Next(10) + 100))          intList.Add(r.Next(10))       Next       For Each val As Integer In intList          Console.Write(val.ToString(  ) + " ")       Next       Console.WriteLine(Environment.NewLine)       For Each emp As Employee In empList          Console.Write(emp.ToString(  ) + " ")       Next       Console.WriteLine(Environment.NewLine)       intList.Sort(  )       empList.Sort(  )       Console.WriteLine("Sorted: ")       For Each val As Integer In intList          Console.Write(val.ToString(  ) + " ")       Next       Console.WriteLine(Environment.NewLine)       For Each emp As Employee In empList          Console.Write(emp.ToString(  ) + " ")       Next    End Sub End Module Public Class Employee    Implements IComparable(Of Employee)    Private employeeID As Integer    Public Sub New(ByVal theID As Integer)       Me.employeeID = theID    End Sub    Public Overrides Function ToString(  ) As String       Return employeeID.ToString(  )    End Function    Public Property EmpID(  ) As Integer       Get          Return employeeID       End Get       Set(ByVal value As Integer)          employeeID = value       End Set    End Property    Function CompareTo(ByVal rhs As Employee) As Integer _        Implements IComparable(Of IComparable.Employee).CompareTo       Return Me.employeeID.CompareTo(rhs.employeeID)    End Function End Class Output: 5 3 7 8 3 8 4 9 7 102 106 100 106 101 107 109 109 106 Sorted: 3 3 4 5 7 7 8 8 9 100 101 102 106 106 106 107 109 109 

The output shows that the integer array and Employee array were generated with random numbers. When sorted, the display shows the values have been ordered properly.



Programming Visual Basic 2005
Programming Visual Basic 2005
ISBN: 0596009496
EAN: 2147483647
Year: 2006
Pages: 162
Authors: Jesse Liberty

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