Reader Level:
ARTICLE

StringBuilder C#

Posted by Puran Mehra Articles | String in C# February 01, 2010
In this article, I will explain you about the StringBuilder Class in C#.
  • 1
  • 0
  • 61746
Download Files:
 

This article has been excerpted from book "The Complete Visual C# Programmer's Guide" from the Authors of C# Corner.

A StringBuilder object is not a string but rather an auxiliary object used for manipulating characters. It contains a buffer, typically initialized with a string but usually larger than that string. This buffer can be manipulated in place without creating a new string: You can insert, append, remove, and replace characters. When you're done manipulating the characters, use StringBuilder's ToString method to extract the finished string from it. 

Both String and StringBuilder contain Unicode characters of type Char and support an indexer that returns Char. Because the String class is immutable, its indexer is read-only, but the StringBuilder indexer is readable/writeable. Listing 20.38 illustrates how to manipulate characters with the StringBuilder class and then place the characters into a String object. 

Listing 20.38: StringBuilder Class Manipulation 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StringBuilderClass
{
    class Program
    {
        static void Main(string[] args)
        {
            String MyName;
            StringBuilder MyOtherName = new StringBuilder("Hello");
            MyOtherName.Remove(2, 3); // produces "He"
            MyOtherName.Insert(2, "lp"); // produces "Help"
            MyOtherName.Replace('l', 'a'); // produces "Heap"
            MyName = MyOtherName.ToString();
        }
    }
}

You can use either String or StringBuilder for string operations. Deciding which to use depends on the frequency of the string modification. If you modify the string frequently-in operations like reassigning, appending, removing, and replacing some characters-you should choose the StringBuilder class. However, if your methods do not change the string value much, registering the String class to the .NET Framework's internal string table will save space in memory for duplicate strings. The framework also provides you faster access to string literal values stored in variables. The .NET Framework automatically handles these operations behind the scenes for you. 

For example, whenever you modify a string in the String class, the methods of the String class returns a new string as the result. Creating many String objects might degrade the performance of your program. You can avoid creating a new instance of a string by using the StringBuilder class. 

Let's say you want to concatenate two strings. Here is the traditional way using the System.String class: 

            string str1 = "I like ";
            string str2 = "Soccer";
            string strConcat = string.Concat(str1, str2);

The value of strConcat is I like Soccer. You can use the StringBuilder class and its Append method to do the same thing: 

            StringBuilder MyStrBuilder = new StringBuilder("I like ");
            String newStr = "Soccer";
            MyStrBuilder.Append(newStr);

The value of MyStrBuilder is I like Soccer. 

You can use the String and StringBuilder classes whenever required and also write auxilliary functions for both classes by providing static helper functions. For example, by default StringBuilder does not provide the IndexOf member function, which does a linear search for a character in a string. But Listing 20.39 shows how you can create your own custom IndexOf function. 

Listing 20.39: StringBuilder IndexOf 

// Example IndexOf function for StringBuilder class

using System;
using System.Text;

public class App
{
    public static int sbIndexOf(StringBuilder sb, char ch)
    {
        Int32 intVal1 = -1;

        while (++intVal1 < sb.Length)
        {
            if (sb[intVal1] == ch)
            {
                return intVal1;
            }
        }
        return -1;
    }

    // string is an alias for System.String in the .NET Framework.

    public static void Main(string[] args)
    {
        StringBuilder sb1 = new StringBuilder(@"Hello There");
        Console.Write("{0}", App.sbIndexOf(sb1, 'o'));
    }
}

Let's look at the subtle difference between String and StringBuilder when passed to a Win32 API function that takes a string. GetWindowText, defined in Windows.h . LpString, points to a buffer of size nMaxCount. That means, before calling GetWindowText, we are expected to allocate a buffer for the pointer of nMaxCount characters: 

            HWND hWnd, // handle to window or control
            LPTStr lpString, // text buffer
            int nMaxCount // maximum number of characters to copy

A fixed-length changeable character buffer must be passed to unmanaged code since LPTStr is a pointer to a character (it is either char* or wchar*, depending on the code compilation choice, ANSI or Unicode). Simply passing a string does not work in this case because GetWindowText cannot modify the contents of the passed buffer. Even if the string is passed by reference, GetWindowText cannot initialize the buffer to a given size. 

The solution in this case is to pass a StringBuilder as the argument in place of a String since a StringBuilder instance can be modified by GetWindowText. Keep in mind that the StringBuilder instance should not exceed the capacity of the StringBuilder. The StringBuilder will be initialized to a fixed length before calling GetWindowText. If you initialize a StringBuilder with a capacity of N, the unmanaged code marshaler uses a buffer of size (N + 1) characters. StringBuilder does not have a null terminator, while the unmanaged string pointer does. 

Listing 20.40 is the code for passing a StringBuilder instance to the GetWindowText API. 

Listing 20.40: GetWindowText in .NET DLL Import 

public class Win32API
{
             [DllImport("User32.Dll")]
             public static extern void GetWindowText(IntPtr handle, StringBuilder s,
            int nMaxCount);
 
            public String GetText(IntPtr handle)
            {
            StringBuilder sb = new StringBuilder(256);
            GetWindowText(handle, sb, sb.Capacity);
            return sb.ToString();
            }

            private void TestGetText()
            {
            MessageBox.Show(GetText(Handle));
            }

Listing 20.41 illustrates StringBuilder usage when building SQL queries. The code segment connects to a Microsoft SQL Server Pubs database, which is installed by default as an example database with predefined options. You'll need to change the SqlClient constructor for use of the example on your computer. 

Listing 20.41: StringBuilder Class 

//stringbuilder

using System;
using System.Data;// for ADO.Net
using System.Data.SqlClient; // for SQL
using System.IO; // for FileStream class
using System.Text; // for StringBuilder class

public class WriteXML
{
    public static void Main()
    {

        // Build a connection
        SqlConnection myConn =
        new SqlConnection("server=vesnet27;uid=sa;pwd=;database=Pubs");

        // Build the SQL string
        StringBuilder mySql = new StringBuilder("SELECT emp_id, fname, lname,hire_date ");
        mySql.Append("FROM employee ");
        mySql.Append("WHERE lname LIKE 'A%' ");
        mySql.Append("ORDER BY lname");
        Console.WriteLine(mySql);

        // Build the DataSet Command object
        SqlCommand myCmd = new SqlCommand(mySql.ToString(), myConn);

        // Build the DataSet
        DataSet myDs = new DataSet();
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.SelectCommand = myCmd;

        // Fill the DataSet with a dataset table named "Products"
        adapter.Fill(myDs);

        // Get a FileStream object
        FileStream myFs =
        new FileStream("myXmlData.xml", FileMode.OpenOrCreate, FileAccess.Write);

        // Use the WriteXml method of DataSet object to write an XML file from
        // the DataSet
        myDs.WriteXml(myFs);
        myFs.Close();
        Console.WriteLine("File Written");
    }
}

The program in Listing 20.41, has this output: 

StringBuilderClass.gif

Conclusion

Hope this article would have helped you in understanding the StringBuilder Class in C#. See other articles on the website on .NET and C#.

visual C-sharp.jpg
The Complete Visual C# Programmer's Guide covers most of the major components that make up C# and the .net environment. The book is geared toward the intermediate programmer, but contains enough material to satisfy the advanced developer.

COMMENT USING

Trending up