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:
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#.
|
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. |