The Essential .NET Data Types

  • 8/15/2011

The String Data Type

Strings are used to store text. Unlike in Visual Basic for Applications (or Visual Basic 6.0), the modern versions of Visual Basic offer an object-oriented programming (OOP) approach for working with strings, which makes string processing much easier. Your programs will be easier to read if you follow the OOP concepts.

You have already encountered strings several times in the previous chapters. Nevertheless, it’s worth taking another look behind the scenes. In conjunction with the Regular Expression (Regex) class, the .NET Framework offers the best possible string support.

In contrast to other base types, strings are reference types. However, you don’t have to define a new String instance with the keyword New. The compiler intervenes here because it has to generate special code anyhow.

The following sections provide an overview of the special characteristic of strings in the BCL. At the end of this section, you’ll find an example application that illustrates the most important string manipulation functions.

Strings—Yesterday and Today

Beginning with Visual Studio 2002 and .NET Framework 1.0, Microsoft introduced a completely new way to approach string programming in Visual Basic. This was the result of the new implementation of the data type String, which is created by instantiating a class, like other objects.

Almost all commands and functions that were “standalone” in Visual Basic 6.0 and VBA still exist in the .NET Framework versions of Visual Basic. But they are not only superfluous—you can reach the same goal much more elegantly with the existing methods and properties of the String object—but they also slow down programs unnecessarily, because internally they call the String object functions anyhow.

For (almost) all the old string functions, there is a corresponding class function that you should use as a substitute. The following sections demonstrate the handling of strings with the help of a few short examples.

Declaring and Defining Strings

As with all other base data types, you can declare strings without using the New keyword; you can perform assignments directly in the program. For example, you can declare a string with the statement:

Dim aString As String

You can then immediately use the new string variable. The instance of the String object is created at IML level. Strings are defined as a list of characters between quotes, as shown in the following example:

aString = "Susan Kallenbach"

Just as with other base data types, declaration and assignment can both take place in an assignment. Therefore, you can combine the two single statements shown in the preceding statements into the following shorter, single statement:

Dim aString As String = "Susan Kallenbach"

Handling Empty and Blank Strings

For decades, Visual Basic developers have become accustomed to using the code pattern shown in the following to check whether a string variable is not defined (Nothing) or points to an empty string:

Dim myString As String
myString = WinFormsTextBox.Text

If myString Is Nothing Or myString = "" Then
     MessageBox.Show("myString is empty.")
End If

Initially, the data type String acts like a regular reference type. As soon as it is declared, it becomes Nothing, because its content points to nothing. But it also has a second state that corresponds to the value “empty,” which occurs when it points to a memory area reserved for saving characters, but that doesn’t contain any characters. In this case, the String variable saves an empty string. Yet a third possibility occurs when the string does contain data (at least from the computer’s standpoint), but that data does not represent visible content, because it’s not printable (or more precisely, it’s not visible on the screen or when printed). Such characters are called whitespace characters, which include space characters, tabs, and other control characters.

All these states are checked by a static method of the String type, and it simplifies testing for such states:

If String.IsNullOrWhiteSpace(myString) Then
    MessageBox.Show("my string is empty.")
End If

When you run this code, you always receive the message “my string is empty” when the myString variable is empty (points to an empty string), is Nothing, or contains only one or more whitespaces.

The method IsNullOrWhiteSpace has been available since .NET Framework 4.0. If you need to maintain backward compatibility with earlier versions of the .NET Framework, or if you want to allow whitespaces as valid entries, it is better to use the IsNullOrEmpty method, which returns True for Nothing and empty strings, as illustrated in the following:

If String.IsNullOrEmpty(myString) Then
    MessageBox.Show("myString is empty.")
End If

Automatic String Construction

Normally, a class constructor creates an instance and a structure to pre-assign certain values to parameters—you’ll find a lot more on constructors in this book’s OOP section.

Even though you create strings in the same manner as all other base data types, you still have the option of calling a constructor method. However, you don’t employ the constructor exclusively for re-instantiating an empty String object (the parameterless constructor is not permitted), but you actually emulate, among others, the old String$ function from Visual Basic 6.0 or VBA.

With their help it was possible to generate a string programmatically and save it in a String variable.

To use the String constructor as a String$ function substitute, do the following:

Dim locString As String = New String("A"c, 40)

The type literal “c” indicates that you need to pass a value of the type Char in the constructor. Unfortunately this limits the repetition function to one character, which wasn’t the case with String$. Fortunately, it’s no problem to implement a Repeat function, which resolves this issue:

Public Function Repeat(ByVal s As String, ByVal repeatitions As Integer) As String
    Dim sBuilder As New StringBuilder

    For count As Integer = 1 To repeatitions
        sBuilder.Append(s)
    Next

    Return sBuilder.ToString
End Function

Apart from using a constructor to generate strings by repeating the same character, you can also use one to create a string from a Char array or a portion of a Char array, as shown in the following example:

Dim locCharArray() As Char = {"K"c, "."c, " "c, "L"c, "ö"c, "f"c, "f"c, "e"c, "l"c, "m"c,
httpatomoreillycomsourcemspimages882161.jpg"a"c, "n"c, "n"c}
Dim locString As String = New String(locCharArray)
Console.WriteLine(locString)
locString = New String(locCharArray, 3, 6)
Console.WriteLine(locString)

When you run this program, the console window displays the following output:

K. Löffelmann
Löffel

Assigning Special Characters to a String

To include quotes in the string itself, use repeated double quotes. For example, to define the string “Adriana said, “it’s only 1pm, I’m going to sleep in a little longer!” in a program, you would write the assignment as follows:

locString = "Adriana said, ""it's only 1pm, I'm going to sleep in a little longer!""."

To include other special characters, use the existing constants in the Visual Basic vocabulary. For example, to build a paragraph into a string, you need to insert the ASCII codes for linefeed and carriage return into the string. You achieve this by using the constants shown in the following example:

locOtherString = "Adriana said ""I'm going to sleep in a little longer!""" & vbCr & vbLf & _
                    "She fell asleep again immediately."

You could use vbNewLine or the shorthand vbCrLf character constants instead. For example, you can save keystrokes with the following version, which delivers the same result:

locOtherString = "Adriana said ""I'm going to sleep in a little longer!""" & vbNewLine & _
                   "She fell asleep again immediately."

Table 6-4 presents the special character constants that Visual Basic offers.

Table 6-4 The Constants That Correspond to the Most Common Special Characters

Constant

ASCII

Description

vbCrLf or vbNewLine

13; 10

Carriage return/line feed character

vbCr

13

Carriage return character

vbLf

10

Line feed character

vbNullChar

0

Character with a value of 0

vbNullString

String with a value of 0. Doesn’t corresponds to a string with a length of 0 (“”); this constant is meant for calling external procedures (COM Interop).

vbTab

9

Tab character

vbBack

8

Backspace character

vbFormFeed

12

Not used in Microsoft Windows

vbVerticalTab

11

Control characters for the vertical tab which isn’t used in Microsoft Windows

Memory Requirements for Strings

Each character in a string requires two bytes of memory. Even though strings are returned as letters, each character is represented in memory by a numeric value. The values from 1 to 255 correspond to the American Standard Code for Information Interchange—ASCII for short—which standardizes only values up to 127 for each character set. Special characters are defined in the 128–255 range, and those characters depend on the specific character set used. Generally the codes for the special characters of the European countries, such as “öäüÖÄÜâéè”, have the same code for each font (the exception proves the rule, as usual). Values above 255 represent special characters that are used, for example, for the Cyrillic, Arabic, or Asian characters. This coding convention, called Unicode, permits a considerably larger total number of characters. The .NET Framework generally saves strings in Unicode format.

No Strings Attached, or Are There? Strings are Immutable!

Generally, strings are reference types, but they are strictly static in memory and are therefore immutable. In practice, that means that there is no restriction as to how you handle strings: even though you might think you have changed a string, you have actually created a new one that contains the changes. You need to know that when it comes to applications that perform many string operations, you should use the StringBuilder class instead, which is noticeably more powerful, even though it doesn’t offer the flexibility of the string manipulation methods or the advantages of the base data types. (The section, “When Speed Matters,” discusses this topic in more detail.)

You can read more about reference and value types in Chapter 8, “Class Begins.”

Much more important is the impact of the immutability of strings in your programs: even though strings are considered reference types, they behave like value types, because they cannot be changed. When two string variables point to the same memory area and you change the content of a string, it appears as though you are changing the value of the original variable, but in reality, such operations create a completely new String object in memory and change the existing variable to point to it. This way, you never end up in the situation you know from reference types, in which changing the object content via the object variable never causes another string variable, which points to the same memory area, to return the edited string. This explains why strings are reference types, but at the same time, they “look and feel” like value types.

You will see more about this in the following section along with some practical examples.

Memory Optimization for Strings

For saving strings the .NET Framework uses an internal pool that to avoids redundancies in string storage. If you define two strings within your program using the same constant, the Visual Basic compiler recognizes that they’re the same and places only one copy of the string in memory. At the same time, it allows both object variables to point to the same memory area, as the following example proves:

Dim locString As String
Dim locOtherString As String

locString = "Adriana" & " Ardelean"
locOtherString = "Adriana Ardelean"
Console.WriteLine(locString Is locOtherString)

When you start this program, it returns True—meaning that both strings point to the same memory area. This condition exists only as long as the compiler can recognize the equality of the strings, and to do this, their values must be specified in a single statement. For example, in the following code, the compiler can no longer recognize the equality of the strings, so the result would be False:

Dim locString As String
Dim locOtherString As String

locString = "Adriana"
locString &= " Ardelean"
locOtherString = "Adriana Ardelean"
Console.WriteLine(locString Is locOtherString)

It’s obvious that a behavior to avoid redundancies at runtime would take too much time and can’t be used in a sensible way. If there are a lot of strings, the BCL would waste too much time searching for strings that already existing. However, you do have the option to specifically add a string created at runtime to a pool. If you add several identical strings to the internal pool, they are not assigned redundantly—several identical strings then share the same memory. Of course, this only makes sense when you can predict that there will be many conformant strings within a program. The example that follows shows how you explicitly add a string with the static function Intern to the internal pool:

Dim locString As String
Dim locOtherString As String

locString = "Adriana"
locString &= " Ardelean"
locString = String.Intern(locString)
locOtherString = String.Intern("Adriana Ardelean")
Console.WriteLine(locString Is locOtherString)

When you start this program, the output is again True.

Determining String Length

VBA/Visual Basic 6.0 compatible command: Len

.NET versions of Visual Basic: strVar.Length

Description: With this command you determine the length of a string in characters, and not in bytes.

Example: The following example accepts a string from a user and returns the string’s characters in inverse order:

Dim locString As String
Console.Write("Enter a text: ")
locString = Console.ReadLine()
For count As Integer = locString.Length - 1 To 0 Step -1
   Console.Write(locString.Substring(count, 1))
Next

You can find the same example with Visual Basic 6.0 compatibility commands in the next section.

Retrieving Parts of a String

VBA/Visual Basic 6.0 compatible command(s): Left, Right, Mid

.NET versions of Visual Basic: strVar.SubString

Description: Use this command to retrieve a certain part of a string as another string.

Example: The following example reads a string from the keyboard and then returns its characters in inverse order. You can find the same example in the previous section with the functions of the String object.

Dim locString As String
Console.Write("Enter a text: ")
locString = Console.ReadLine()
For count As Integer = Len(locString) To 1 Step -1
    Console.Write(Mid(locString, count, 1))
Next

Padding Strings

VBA/Visual Basic 6.0 compatible command(s): RSet, LSet

.NET versions of Visual Basic: strVar.PadLeft; strVar.PadRight

Description: With these commands, you can increase the length of a string to a certain number of characters; the string is padded with blank characters at the beginning or the end.

Example: The following example demonstrates the use of the PadLeft and the PadRight method:

Dim locString As String = "This string is so long"
Dim locString2 As String = "Not this one"
Dim locString3 As String = "This"
Len(locString)
locString2 = locString2.PadLeft(locString.Length)
locString3 = locString3.PadRight(locString.Length)

Console.WriteLine(locString + ":")
Console.WriteLine(locString2 + ":")
Console.WriteLine(locString3 + ":")

When you run this program the following output is generated:

This string is so long:
          Not this one:
This                  :

Find and Replace Operations

VBA/Visual Basic 6.0 compatible command(s): InStr, InStrRev, Replace

.NET versions of Visual Basic: strVar.IndexOf; strVar.IndexOfAny; strVar.Replace; strVar.Remove

Description: With the Visual Basic 6.0 compatible command InStr, you can search for the occurrence of a character or a string within a string. InStrRev does the same, but it starts the search from the end of the string. Replace lets you to replace a substring within a string with another string.

Using the IndexOf method of the String class, you can search for the occurrence of a character or a string within the current string. Furthermore, the IndexOfAny method lets you find the occurrences of a group of characters passed as a Char array within the string. The Replace method replaces individual characters or strings with others in the current string, and the Remove method removes a specific substring from the string.

Example: The following examples demonstrate how to use the Find and Replace methods of the String class:

Imports System.Globalization

Module Strings
    Sub Main()
        Dim locString As String = _
            "Common wisdoms:" + vbNewLine + _
            "* If you would shout for 8 years, 7 months, and 6 days," + vbNewLine + _
            "  you would have produced enough energy to heat a cup of coffee." + _
httpatomoreillycomsourcemspimages882161.jpgvbNewLine + _
            "* If you hit your head against the wall, you use up 150 calories." +
httpatomoreillycomsourcemspimages882161.jpgvbNewLine + _
            "* Elephants are the only animals who can't jump." + vbNewLine + _
            "* A cockroach can live for 9 days without a head before it dies of
httpatomoreillycomsourcemspimages882161.jpghunger." + vbNewLine + _
            "* Gold and other metals originate solely from" + vbNewLine + _
            "  supernovae." + vbNewLine + _
            "* The Moon consists of debris from a collision of a" + vbNewLine + _
            "  planet the size of Mars with the Earth." + vbNewLine + _
            "* New York is called the ""Big Pineapple"", because ""Big Pineapple"" in
httpatomoreillycomsourcemspimages882161.jpgthe language of" + vbNewLine + _
            "  Jazz musicians meant ""hitting the jackpot"". To have a career in New
httpatomoreillycomsourcemspimages882161.jpgYork" + vbNewLine + _
            "  meant their jackpot." + vbNewLine + _
            "* The expression ""08/15"" for something unoriginal was originally " +
httpatomoreillycomsourcemspimages882161.jpgvbNewLine + _
            "  the label of the machine gun LMG 08/15;" + vbNewLine + _
            "  It become the metaphor for unimaginative, military drills." +
httpatomoreillycomsourcemspimages882161.jpgvbNewLine + _
            "* 311 New Yorkers are being bit by rats per year in average." +
httpatomoreillycomsourcemspimages882161.jpgvbNewLine + _
            "  But 1511 New Yorkers have been bit by other New Yorkers at the same
httpatomoreillycomsourcemspimages882161.jpgtime."
        'Replace number combination with letters
        locString = locString.Replace("08/15", "Zero-eight-fifteen")

        'Count punctuation
        Dim locPosition, locCount As Integer

        Do
            locPosition = locString.IndexOfAny(New Char() {"."c, ","c, ":"c, "?"c},
httpatomoreillycomsourcemspimages882161.jpglocPosition)
            If locPosition = -1 Then
                Exit Do
            Else
                locCount += 1
            End If
            locPosition += 1
        Loop

        Console.WriteLine("The following text...")
        Console.WriteLine(New String("="c, 79))
        Console.WriteLine(locString)
        Console.WriteLine(New String("="c, 79))
        Console.WriteLine("...has {0} punctuation.", locCount)
        Console.WriteLine()
        Console.WriteLine("And after replacing 'Big Pineapple' with 'Big Apple' it
httpatomoreillycomsourcemspimages882161.jpglooks as follows:")
        Console.WriteLine(New String("="c, 79))

        'Another substitution
        locString = locString.Replace("Big Pineapple", "Big Apple")
        Console.WriteLine(locString)
        Console.ReadLine()

    End Sub

End Module

The example displays the following output on the screen:

The following text...
===============================================================================
Common wisdoms:
* If you would shout for 8 years, 7 months, and 6 days,
  you would have produced enough energy to heat a cup of coffee.
* If you hit your head against the wall, you use up 150 calories.
* Elephants are the only animals who can't jump.
* A cockroach can live for 9 days without a head before it dies of hunger.
* Gold and other metals originate solely from
  Supernovae.
* The Moon consists of debris from a collision of a
  planet the size of Mars with the Earth.
* New York is called the "Big Pineapple", because "Big Pineapple" in the language of
  Jazz musicians meant "hitting the jackpot". To have a carreer in New York
  meant their jackpot.
* The expression "08/15" for something unoriginal was originally
  the label of the machine gun LMG 08/15;
  It become the metaphor for unimaginative, military drills.
* 311 New Yorkers are being bit by rats per year in average.
  But 1511 New Yorkers have been bit by other New Yorkers at the same time.
===============================================================================
...has 23 punctuation marks.

And if you replace 'Big Pineapple' with 'Big Apple' it looks as follows:
===============================================================================
Common wisdoms:
* If you would shout for 8 years, 7 months, and 6 days,
  you would have produced enough energy to heat a cup of coffee.
* If you hit your head against the wall, you use up 150 calories.
* Elephants are the only animals who can't jump.
* A cockroach can live for 9 days without a head before it dies of hunger.
* Gold and other metals originate solely from
  Supernovae..
* The Moon consists of debris from a collision of a
  planet the size of Mars with the Earth.
* New York is called the "Big Apple", because "Big Apple" in the language of
  Jazz musicians meant "hitting the jackpot". To have a carreer in New York
  meant their jackpot.
* The expression "08/15" for something unoriginal was originally
  the label of the machine gun LMG 08/15;
  It become the metaphor for unimaginative, military drills.
* 311 New Yorkers are being bit by rats per year in average.
  But 1511 New Yorkers have been bit by other New Yorkers at the same time.

Trimming Strings

VBA/Visual Basic 6.0 compatible command(s): Trim, RTrim, LTrim

.NET versions of Visual Basic: strVar.Trim, strVar.TrimEnd, strVar.TrimStart

Description: These methods remove characters from both the beginning and the end of a string (Trim) or at either end of a string (TrimStart and TrimEnd). For these methods, the object methods of the strings are preferable to the compatibility functions, because for the former you can also specify which characters should be trimmed, as the following example demonstrates. In contrast, the Visual Basic 6.0 compatibility functions only allow space characters to be trimmed.

Example: The following example generates a String array whose individual elements have unwanted characters at the beginning and the end (not just space characters), which are removed by using the Trim function.

Dim locStringArray() As String = { _
   "  - Here the actual text starts!", _
   "This text ends with strange characters! .-     ", _
   "  - Here both sides are problematic -  "}

For Each locString As String In locStringArray
   locString = locString.Trim(New Char() {" "c, "."c, "-"c})
   Console.WriteLine("Clean and neat: " + locString)
Next

'Important: String is a reference type, but nothing has changed for the array.
'That's because strings aren't changed directly, but are always created anew and thus
changed.
For Each locString As String In locStringArray
   Console.WriteLine("Still messy: " + locString)
Next

If you run this program, the following output is generated:

Clean and neat: Here the actual text starts!
Clean and neat: This text ends with strange characters!
Clean and neat: Here both sides are problematic
Still messy:   - Here the actual text starts!
Still messy: This text ends in strange characters! .-
Still messy:   - Here both sides are problematic –

Splitting Strings

VBA/Visual Basic 6.0 compatible command(s): Split

.NET versions of Visual Basic: strVar.Split

Description: The .NET Split method of the String class is superior to the compatibility function in that it permits you to specify several separator characters in a Char array. This makes your programs more flexible when it comes to analyzing and rebuilding text.

Example: The following example separates the individual terms or sections of a string into partial strings separated by different separator characters. These separated strings are later presented as elements of a String array and are further prepared with additional functions.

Module Strings
    Sub Main()
        Dim locString As String = _
           "Individual, elements; separated by, different - characters."
        Console.WriteLine("From the line:")
        Console.WriteLine(locString)
        Console.WriteLine()
        Console.WriteLine("Becomes a string array with the following elements:")
        Dim locStringArray As String()
        locStringArray = locString.Split(New Char() {","c, ";"c, "-"c, "."c})
        For Each locStr As String In locStringArray
            Console.WriteLine(ReplaceEx(locStr, New Char() {","c, ";"c, "-"c, "."c}, _
                   Convert.ToChar(vbNullChar)).Trim)
        Next
        Console.ReadLine()
    End Sub

    Public Function ReplaceEx(ByVal str As String, ByVal SearchChars As Char(), _
                        ByVal ReplaceChar As Char) As String
        Dim locPos As Integer
        Do
            locPos = str.IndexOfAny(SearchChars)
            If locPos = -1 Then Exit Do
            If AscW(ReplaceChar) = 0 Then
                str = str.Remove(locPos, 1)
            Else
                str = str.Remove(locPos, 1).Insert(locPos, ReplaceChar.ToString)
            End If
        Loop
        Return str
    End Function
End Module

When you run this program, it generates the following output:

The line:
Individual, elements; separated, by, different- characters.

Becomes a string array with the following elements:
Individual
elements
separated
by
different
characters

Iterating through Strings

The following code segment uses a further variation for iterating through the individual characters in a string. The Chars property of a String object is an array of Char values, which represent the individual characters in the string. Because the String object also offers the function GetEnumerator, you have the following option for iterating via a string:

For Each locChar As Char In "This is a string"
   'Do something.
Next

Thanks to the power of the String class, the functions Find and Replace are surprisingly easy to implement. In the following code, assume that the fneFiles collection contains a list of file names:

Private Sub btnCheckFound_Click(ByVal sender As System.Object, ByVal e As System.
httpatomoreillycomsourcemspimages882161.jpgEventArgs) _
                Handles btnCheckFound.Click
    For Each locFEI As FilenameEnumeratorItem In fneFiles.Items
        Dim locFilename As String = locFEI.Filename.Name
        If locFilename.IndexOf(txtSearch.Text) > -1 Then
            locFEI.Checked = True
        Else
            locFEI.Checked = False
        End If
    Next
End Sub

Private Sub btnReplaceChecked_Click(ByVal sender As System.Object,ByVal e As System.
httpatomoreillycomsourcemspimages882161.jpgEventArgs) _
    Handles btnReplaceChecked.Click
    For Each locFEI As FilenameEnumeratorItem In fneFiles.Items
        Dim locFilename As String = locFEI.SubItems(1).Text
        If locFEI.Checked Then
            If locFilename.IndexOf(txtSearch.Text) > -1 Then
                locFilename = locFilename.Replace(txtSearch.Text, txtReplace.Text)
                locFEI.SubItems(1).Text = locFilename
            End If
        End If
    Next
End Sub

StringBuilder vs. String: When Performance Matters

As you saw earlier in this chapter, .NET provides you with extremely powerful tools for processing strings. If you read the section on memory management, you probably noticed that string processing speed in certain scenarios leaves much to be desired. The reason is simple: strings are immutable. If you are working with algorithms that build strings character-by-character, then for every character you add to the string, a completely new string must be created—and that takes time.

The StringBuilder class represents an alternative for such operations. In no way does it provide the functionality of the String class in terms of methods, but it does offer an essential advantage: it is managed dynamically, and therefore, it is disproportionately faster. When it comes to building strings (by appending, inserting, or deleting characters), you should use a StringBuilder instance—especially when you’re dealing with large amounts of data.

Using the StringBuilder class is quite simple. First, you need to declare the System.Text namespace, which you can bind into your class or module file with an Imports statement, as follows:

Imports System.Text

Next, you simply declare a variable with the type StringBuilder, and then initialize it with one of the following constructor calls:

'Declaration without parameters:
Dim locSB As New StringBuilder
'Declaration with capacity reservation
locSB = New StringBuilder(1000)
'Declaration from an existing string
locSB = New StringBuilder("Created from a new string")
'Declaration from string with the specification of a capacity to be reserved
locSB = New StringBuilder("Created from string with capacity for more", 1000)

Note that you can specify an initial capacity when defining a StringBuilder object. This way, the space that your StringBuilder object will eventually require is reserved immediately—no additional memory needs to be requested at runtime, which improves performance.

To add characters to the string, use the Append method. Using Insert, you can place characters anywhere into the string stored in the StringBuilder object. Replace lets you replace one string with another, whereas Remove deletes a specified number of characters from a specific character position onward. Here’s an example:

locSB.Append(" – and this gets appended to the string")
locSB.Insert(20, ">>this ends up somewhere in the middle<<")
locSB.Replace("String", "StringBuilder")
locSB.Remove(0, 4)

When you have finished building the string, you can convert it into a “real” string by using the ToString function:

'StringBuilder has finished building the string
'Convert to string
Dim locString As String = locSB.ToString
Console.WriteLine(locString)

When you execute the preceding statements, the console window displays the following text:

StringBuilder Create>>this ends up somewhere in the middle<<d from string with capacity for
more – and that is added to the StringBuilder

Performance Comparison: String vs. StringBuilder

This section’s project demonstrates the efficiency of the StringBuilder class. The program creates a number of String elements, each consisting of a fixed number of random characters. When you start the program, enter the values of the following parameters as prompted:

Enter the string length of an element: 100
Enter a number of elements to be generated: 100000

Generating 100000 string elements with the String class...
Duration: 2294 milliseconds

Generating 100000 string elements with the StringBuilder class...
Duration: 1111 milliseconds

The preceding code demonstrated that using the StringBuilder class with an element length of 100 characters already doubles the speed. Restart the program. To see a really impressive increase in speed, enter an element length of 1000 and specify the value of 10000 for the number of elements to be generated, as shown in the following example:

Enter the string length of an element: 1000
Enter a number of elements to be generated: 10000

Generating 10000 string elements with the String class...
Duration: 6983 milliseconds

Generating 10000 string elements with the StringBuilder class...
Duration: 1091 milliseconds

With these parameters, the StringBuilder is approximately six times faster than the String class. The lengthier the generated strings, the more sense it makes to use a StringBuilder object.

The program relies on the StopWatch class for timing the operations. With this class, you can measure time durations with extreme precision—and it’s simple to use. The following code sample, which reuses some code from earlier in the chapter, shows its use:

Imports System.Text

Module StringsVsStringBuilder

    Sub Main()
        Dim locAmountElements As Integer
        Dim locAmountCharsPerElement As Integer
        Dim locVBStringElements As VBStringElements
        Dim locVBStringBuilderElements As VBStringBuilderElements

        'StringBuilderExamples()
        'Return

        Console.Write("Enter the string length of an element: ")
        locAmountCharsPerElement = Integer.Parse(Console.ReadLine)
        Console.Write("Enter a number of elements to be generated: ")
        locAmountElements = Integer.Parse(Console.ReadLine)
        Console.WriteLine()
        Console.WriteLine("Generating " & locAmountElements &
                    " string elements with the String class...")
        Dim locTimeGauge = Stopwatch.StartNew
        locVBStringElements = New VBStringElements(locAmountElements,
httpatomoreillycomsourcemspimages882161.jpglocAmountCharsPerElement)
        locTimeGauge.Stop()
        Console.WriteLine("Duration: " & locTimeGauge.ElapsedMilliseconds.ToString())
        locTimeGauge.Reset()
        Console.WriteLine("Generating " & locAmountElements &
                    " string elements with the StringBuilder class...")
        locTimeGauge.Start()
        locVBStringBuilderElements =
                    New VBStringBuilderElements(locAmountElements,
httpatomoreillycomsourcemspimages882161.jpglocAmountCharsPerElement)
        locTimeGauge.Stop()
        Console.WriteLine("Duration: " & locTimeGauge.ElapsedMilliseconds.ToString())
        locTimeGauge.Reset()
        Console.WriteLine()
        Console.ReadLine()
    End Sub

    Sub StringBuilderExamples()

        'Declaration without parameters:
        Dim locSB As New StringBuilder
        'Declaration with capacity reservation
        locSB = New StringBuilder(1000)
        'Declaration from an existing string
        locSB = New StringBuilder("Created from a new string")
        'Declaration from string with the specification of a capacity to be reserved
        locSB = New StringBuilder("Created from string with capacity for more", 1000)

        locSB.Append(" - and this gets appended to the string")
        locSB.Insert(20, ">>this ends up somewhere in the middle<<")
        locSB.Replace("String", "StringBuilder")
        locSB.Remove(0, 4)

        'StringBuilder has finished building the string
        'Convert to string umwandeln
        Dim locString As String = locSB.ToString
        Console.WriteLine(locString)
        Console.ReadLine()
    End Sub

End Module

Public Class VBStringElements

    Private myStrElements() As String

    Sub New(ByVal AmountOfElements As Integer, ByVal AmountChars As Integer)

        ReDim myStrElements(AmountOfElements - 1)
        Dim locRandom As New Random(DateTime.Now.Millisecond)
        Dim locString As String

        For locOutCount As Integer = 0 To AmountOfElements - 1
            locString = ""
            For locInCount As Integer = 0 To AmountChars - 1
                Dim locIntTemp As Integer = Convert.ToInt32(locRandom.NextDouble * 52)
                If locIntTemp > 26 Then
                    locIntTemp += 97 - 26
                Else
                    locIntTemp += 65
                End If
                locString += Convert.ToChar(locIntTemp).ToString
            Next
            myStrElements(locOutCount) = locString
        Next
    End Sub

End Class

Public Class VBStringBuilderElements

    Private myStrElements() As String

    Sub New(ByVal AmountOfElements As Integer, ByVal AmountChars As Integer)

        ReDim myStrElements(AmountOfElements - 1)
        Dim locRandom As New Random(DateTime.Now.Millisecond)
        Dim locStringBuilder As StringBuilder

        For locOutCount As Integer = 0 To AmountOfElements - 1
            locStringBuilder = New StringBuilder(AmountChars)
            For locInCount As Integer = 0 To AmountChars – 1
                Dim locIntTemp As Integer = Convert.ToInt32(locRandom.NextDouble * 52)
                If locIntTemp > 26 Then
                    locIntTemp += 97 - 26
                Else
                    locIntTemp += 65
                End If
                locStringBuilder.Append(Convert.ToChar(locIntTemp))
            Next
            myStrElements(locOutCount) = locStringBuilder.ToString
        Next
    End Sub

End Class