|
A Few of My Favorite (.Net) Things
4/21/2007
Favorite Things
There are thousands of classes in the .Net framework that are provided to help you do just about anything you want in your software. When you begin learning .Net this can seem overwhelming. But you don’t have to learn them all, or even most of them to be able to create effective applications. Some classes are highly specialized and you usually don’t learn how to use them until you need the functionality they provide. But I have found a few classes that are widely useful in many programming situations. In other words, I use them all the time. Here I will describe three that I think are very useful and that you might not be familiar with if you are coming from another programming environment. These classes are the StringBuilder, the ArrayList and the HashTable. Since they are part of the .Net framework, they can be used with either Visual Basic.Net or C#.
StringBuilder
If you are involved in processing text, either as in input or an output, the StringBuilder class can make a huge difference in the performance of you application. This class helps you concatenate strings together into one long string, without the performance penalty you pay with string variables. Variables of type String are said to be immutable. This means that once the string value is assigned, it cannot be changed. But of course, we can change the value of a string variable in code. So what is happening here? When a string variable is used, a chunk of memory is allocated to store the value assigned to the string. For example, if we have a variable named strTemp that is assigned a value:
Dim strTemp as String
strTemp = “xyz”
Enough memory is allocated to store the value “xyz” for the variable. What if we later want to add on to the string?
strTemp = strTemp & “abc”
The memory location in use can’t be reused. Instead, a new memory location is allocated with enough space to hold the original contents of strTemp plus the new string that we want to add on. The variable strTemp then points to the new location in memory. This may not seem like a big deal. And indeed if you just do it once or twice, it isn’t. But what happens if you are concatenating a string hundreds or thousands of times?
For I As Integer = 0 to 10000
strTemp &= “abcdefghijklmnopqrstuvwxyz”
Next
This loop concatenates a string value onto the value of strTemp ten thousand times. I used the alphabet as a sample string. But in real life you might be building the contents of a text file from data, or creating XML as text, or creating an HTML document as text, or many other similar operations. Each time through the loop, memory must be reallocated to perform the concatenation. And each time, the amount of memory needed and the copying from the old location to the new increases as the size of the string gets bigger. The end result is that the more concatenation you application does, the less efficient it becomes.
The StringBuilder class solves this problem. It holds a string value and allows you to append to that value repeatedly without having a memory allocation every time. It does this by managing its own memory. It starts of by pre-allocating a chunk of memory. Then as you begin to append values, this memory is used. If that chunk of memory gets filled up, the StringBuilder then doubles its memory allocation automatically.
The code to use the StringBuilder looks like this:
Dim sb As New StringBuilder()
For I As Integer = 0 to 10000
sb.Append(“abcdefghijklmnopqrstuvwxyz”)
Next
You use the Append method to concatenate a string onto the contents of the StringBuilder. When you want to get the final string back from the StringBuilder object, just use the toString method.
Return sb.toString
If you have a fair idea of how big the final result will be, you can specify the initial size of the StringBuilder memory allocation in the constructor.
Dim sb As New StringBuilder(1000)
This stringbuilder will have enough memory to hold 1000 characters. If you exceed that amount, it will still increase its memory as described above.
ArrayList
Very often we use an array in our code to store a list of items that go together. Arrays in .Net provide all the capability you are used to, as well as some convenient functions such as sorting. Many times though, we use an array not knowing how many elements are going to be in the array until run time. For example, you might be reading a set of data from a database, and you don’t know when you are writing the code how many rows there will be in the data. If you use an array you have to either use ReDim to resize the array, or declare an extremely large array that would be bigger than any possible set of data.
Neither of these options is efficient, or bullet proof. The .Net framework provides a much better solution. The ArrayList object allows you to create a list of items without knowing how many items there will be. Instead of declaring an array with a set number of elements, you simply create an instance of an ArrayList, and use the Add method to add items to it. Like the Stringbuilder, the ArrayList will automatically increase its capacity to hold however many elements you need.
Dim AL as New ArrayList()
AL.Add(“Some text”)
AL.Add(“More text”)
AL.Add(123)
The elements in the ArrayList are of type Object, which means you can store anything in an ArrayList. While you will most likely store a list of text strings, or a list of numbers, you could also store a list form controls, or even a list of arrays. You can even have a list of objects that are of different types. In the code example above, you can see that the first two items added to the list are text strings, but the third is a number (Integer). The ArrayList doesn’t prevent you from doing this, but it isn’t good programming practice.
The ArrayList object implements the IList interface. This is a very important interface in the .Net framework that you need to be familiar with. It provides standard properties and methods for objects that represent collections that allow you to do things like access the elements by index. The Item property is the default property, and returns the object at the specified index. This is useful if you want to return a specific item in the arraylist. If you want to iterate through the whole list, you can use the ‘For Each’ syntax in a loop. So to loop through the list of elements in the ArrayList you do this:
Dim Obj as Object
For Each Obj in ArrayList
Console.WriteLine(Obj.ToString)
Next
There are some limitations to the ArrayList object. As mentioned before, the elements stored are of type Oject. So it is up to you as the programmer to make sure that the ArrayList stores only items that are compatible, and also to make any necessary type conversions. Otherwise you may be faced with some run-time errors that can be difficult to diagnose. Also, the ArrayList is only a one-dimensional array. If you want to store multidimensional data, you may consider having each element of the ArrayList be an array, or even another ArrayList.
HashTable
Sometimes you store a list of items in code and then use that list as a look up table for other parts of your application. You can implement this in an array, but the resulting searches through that array to find elements can be very inefficient. The Hashtable object provides a list of key-value pairs. The value part of the pair is the information you are storing, and the key is a look-up value. You may have used a similar object in the past called a dictionary object. The difference here is that the Hashtable stores the hash code of the key and uses hashing to look up values.
A hash is a mathematical function that is applied to an input to produce a numerical output. The hash function is designed to guarantee a unique output for every unique input. The Hashtable hashes the key when you add an entry. Then later, when want to look up something, the input is hashed and compared to the stored hash values. This is much faster than having to do character comparisons for each key.
You don’t have to know anything about the hash function itself in order to be able to use the Hashtable. Its use is very similar to the ArrayList object.
Dim hCaps as New HashTable()
hCaps.Add(“CA”, “Sacramento”)
hCaps.Add(“MO”, “Jefferson City”)
Here is an example of a Hashtable that stores state capitals and allows you to look them up by the state’s two letter abbreviation. In the Add method you specify the key (“CA”) and the value (“Sacramento”).
Both parameters of the Add method are of type Object. The key can be any object that implements Object.GetHashCode and Object.Equals. You will find that most often, the keys you are using are strings or numbers, both of which work just fine. The value can be any object. So the Hashtable can store arrays, lists, or even other Hashtables.
Later in your code, when you want to look up the capital of a state, you can just use the default Item property, passing in the key. If the key is found, the value is returned, otherwise Nothing is returned.
myCap = hCaps(“CA”)
This returns “Sacramento” in the myCap variable.
You can also use the Contains method to determine if the Hashtable contains the specified key, without returning the value associated with the key.
If myCap.Contains(“CA”) Then
Return True
End If
There are a few other ways to access the data in the Hashtable. You can explore them on your own as you begin using the Hashtable.
In this article I showed you three easy to use objects in the .Net framework that can make your applications more efficient. There is more to learn about each of them, but hopefully you have enough to begin using them. When you look at your code, places that do repetitive concatenating of text strings are good candidates for the Stringbuilder. And anywhere that you are using arrays, look to see if the ArrayList or the Hashtable would be more appropriate.
|