Everyday Use of Generics You may think of generics as a Ferrari that you only take out for special occasions; but they are better compared to your trusty pickup, perfectly suited for everyday use. It would be nice to begin by saying in simple terms what generic are … but it is hard to explain exactly what generics are. Generics are not really a single thing but rather a set of techniques with a single purpose: to work with generalized code in a data type-specific way. | " | With the built-in generic collection classes you may never need to dimension an array again!
| " |
This somewhat complex-sounding purpose is why it may appear that generics are a Ferrari-style technique. But getting past the definition to actual examples will demonstrate how you can use generics every day to minimize the amount of code you write and improve the performance of your applications. The two most fundamental and potentially “everyday” generics techniques involve the built-in generics collections and generic methods. If you ever use arrays or ArrayLists in your applications, consider using the built-in generics collections instead. The built-in generics collections are not only easier to use than arrays, but they allow you to limit the data type of the items that are in the collection. This provides type-safety, meaning that a compile-time error is generated if the code attempts to put something in the collection that is not of the correct type. It can also improve the performance of the application, limiting conversion of data types. Generic methods provide a way for you to write code that can work with any data type. You then specify the data type that you want to use when you call the code. This minimizes repetitive code and maximizes type safety. For both techniques, generics provide for code (either that you write or that is in the Framework) that will work with any data type, such as strings, integers, business objects, etc. You then specify the data type that the code should use when you call that code. That allows you to reuse that code for any number of data types. This article demonstrates how to use the built-in generic collections instead of arrays. It then details other uses of generic collections, such as for data binding and sorting. Finally, it describes how to build your own generic methods to take advantage of generics every day. Using Generics Instead of Arrays Arrays are a common mechanism for storing data in an application. You may currently use them to store internal data or user-entered values. But working with arrays is somewhat complex. First you need to set up their dimension, and then you need to keep track of how many items you are adding to the array so you don’t exceed their dimension. For example, the following code takes user-entered names and adds them to an array: Private NameArray(5) As String Private NameArrayIndex As Integer = 0
…
If NameArrayIndex > 5 Then ReDim Preserve NameArray(NameArray.Length + 5) End If NameArray(NameArrayIndex) = NameTextBox.Text NameArrayIndex += 1
If you instead use one of the built-in generic collections, you can replace the two declarations with one and replace the five lines of code to manage the array with one line of code: Private NameList As New List(Of String)
…
NameList.Add(NameTextBox.Text)
Note: If Visual Studio does not recognize the List keyword, examine your project imports (My Project, References Tab, Imported Namespaces section). Ensure that System.Collections.Generic is checked. Or prefix the List keyword with System.Collections.Generic. The declaration in this example creates a new instance of the List built-in generic collection. The “Of String” syntax is used to identify the type parameter and defines the specific data type to use with the generic collection. In this case, only strings can be added to the collection. Note: You will often see generics documented using “Of T” such as List(Of T). The T is the placeholder for the type parameter and can be replaced with any data type when using the generics collection or method. If the code attempts to put something other than a string into the collection, the code generates a compile-time error. For example: NameList.Add(1)
This line will generate the error: “Option Strict On disallows implicit conversions from 'Integer' to 'String'”. (Assuming of course that you have Option Strict On.) If you want to retain key and value pairs, such as U.S. states along with their abbreviations, you can use a generic Dictionary. Generic Dictionaries have two type parameters, a unique key and a value. Note: Do not confuse these generic Dictionaries with the old scripting Dictionaries sometimes used in Visual Basic 6.0 applications. The following code creates a new generic Dictionary and adds the abbreviation as the key and the long name as the value: Private StateDictionary As New Dictionary(Of String, String)
…
StateDictionary.Add("CA", "California") StateDictionary.Add("NY", "New York") StateDictionary.Add("WI", "Wisconsin") …
Even though the code examples so far showed Strings as the type parameters, you can use any data type as the key or as the value. For example, if you had a Person business object with a unique numeric ID, you could define a PersonDictionary as follows: Private PersonDictionary As New Dictionary(Of Integer, Person)
The .NET Framework provides for several different types of generic collections. The ones that you may use most often include: - Dictionary: Provides a list of key and value pairs where the key must be unique. For example PersonDictionary(Of Integer, Of Person) represents a collection of Person objects keyed by a unique integer value.
- List: Provides a list of values that can be accessed by index. For example PersonList(Of Person) represents a list of Person objects. The List provides methods to search, sort, and manipulate lists.
- SortedDictionary: Provides a generic Dictionary that is sorted by the unique key.
- SortedList: Provides a generic List that is sorted by a unique key.
Each of these generic collections provides better type safety and performance than non-generic collections and is much easier to use than arrays. With the built-in generic collection classes you may never need to dimension an array again! |