Visual CSharp .NET Programming (2002) [eng]
.pdfstring str = null;
Initializing a string to null is not the same as initializing it to an empty string:
string str = "";
In the case of the null assignment, no memory has been allocated for the string. An attempt to determine the length of a null string-by using its Length property-causes an exception to be thrown. In contrast, the Length property of an empty string is 0.
Note An alternate way to initialize an empty string is to use the static Empty field of the String class: string str = string.Empty;.
Methods
When you pass a method a string literal, you are also creating a string. This is the case for prebuilt methods, such as the Show method of the MessageBox class:
MessageBox.Show ("Thanks for making me a string!");
This is also the case when you send a string literal argument to a user-defined method with a string parameter:
MakeAStr ("'Tis noble to be a string!");
...
private void MakeAStr (string str) { // Do something with str txtDoIt.Text = str;
}
It's also the case that many methods create strings as their return value. This is famously so for the System.Object class's ToString method. All classes derive from Object, so all types provide a ToString method, which is intended to return a string that represents the current object. For example, the expression
42.ToString();
returns the string '42'.
Note In your own classes, it is your responsibility to provide a ToString method that returns a string that represents the objects based on your classes. The "Implementing the ToString Method" section later in this chapter provides an example.
Many other .NET Framework class methods besides ToString return strings. As one good example, have a look at the System.Convert class, which sports 36 different static (overloaded) Convert.ToString methods, each of which returns a string. Some of these are shown in the Object Browser in Figure 9.2.
Figure 9.2: Each of the 36 overloaded Convert.ToString methods returns a string.
String Constructors
The String class itself has eight constructors. If you look in the Object Browser, you'll find that five of these use pointers and are not safe under the Common Language Specification (CLS).
The unsafe constructors are not discussed here (to find out more about them, look up 'String Constructor' in online help). The remaining three safe String overloaded constructor methods are shown in Table 9.2.
|
|
Table 9.2: Overloaded Safe String Class Constructors |
|
|
|
Method |
|
Meaning |
|
|
|
String |
|
Creates a string consisting of a char repeating int times. |
(char, |
|
|
int) |
|
|
|
|
|
String |
|
Creates a string from a char array. |
(char[]) |
|
|
|
|
|
String |
|
Create a string from a char array with a start position and length. |
(char[], |
|
|
int, int) |
|
|
|
|
|
Let's have a look at an example that uses these constructors. It's easy to use the first form and create a string consisting of the lowercase letter a 23 times:
string str1 = new String ('a', 23);
To use the second form, we must first create a char array:
char [] achra = new char[6] {'H', 'e', 'l', 'l' ,'o', '!'}; string str2 = new String (achra);
Third time pays for all! First, let's initialize a string:
string str3 = "Beasts of England";
Next, we can use the string's ToCharArray method to turn it into a char array:
char [] achra2 = str3.ToCharArray();
Finally, it's a hop, skip, and a jump to assign the first six elements of the char array to a string:
str3 = new String (achra2,0,6);
Listing 9.1 shows the code that uses the three constructors and displays the results in a ListBox.
Listing 9.1: The Safe String Constructors
private void btnStr_Click(object sender, System.EventArgs e) { lstStr.Items.Clear();
string str1 = new String ('a', 23);
char [] achra = new char[6] {'H', 'e', 'l', 'l' ,'o', '!'}; string str2 = new String (achra);
string str3 = "Beasts of England"; char [] achra2 = str3.ToCharArray(); str3 = new String (achra2,0,6); lstStr.Items.Add (str1); lstStr.Items.Add (str2); lstStr.Items.Add (str3);
}
Verbatim Strings
In Chapter 6, I mentioned that you could use the @ symbol to use a keyword as an identifierif you were so inclined, you could create variables named, for example, @if, @string, and @true. (To repeat what I said back in Chapter 6, just because one can do something, doesn't mean it is a good idea.)
In the context of strings, the @ symbol is used to create verbatim string literals. The @ symbol tells the string constructor to use the string literal that follows it "literally"-even if it includes escape characters or spans multiple lines.
This comes in handy when working with directory paths (without the @, you would have to double each backslash). For example, the following two strings are equivalent:
string noat = "\\\\BIGSERVER\\C"; string withat = @"\\BIGSERVER\C";
Here's how you could use the @ symbol to take the place of the \r\n escape sequence of control characters, which means "carriage return, new line":
private void btnVer_Click(object sender, System.EventArgs e) { string str =
@"It's fun to be
split into a number of lines!";
txtDoIt.Text = str;
}
If you assign the verbatim string to a TextBox that has its Multiline property set to True, you'll see that the line breaks (and white spaces) are preserved exactly as entered in the verbatim string.
If you are curious, here's how you'd create the same string as a non-verbatim string, using the control characters and string concatenation:
string str = "It's fun\r\n |
to be\r\n"+ |
|
" |
split into a number\r\n" + |
|
" |
|
of lines!"; |
txtDoIt.Text = str; |
|
|
String Methods
The String class provides many powerful instance and static methods. These methods are described in this section. Most of these methods are overloaded, so there are multiple ways that each can be used.
Instance Methods
Table 9.3 describes many of the instance methods of the String class.
Table 9.3: Instance Methods of the String Class
Method |
|
What It Does |
|
|
|
Clone |
|
Returns a reference to the instance of the string. |
|
|
|
CompareTo |
|
Compares this string with another. |
|
|
|
CopyTo |
|
Copies the specified number of characters from the string instance to a char |
|
|
array. |
|
|
|
EndsWith |
|
Returns true if the specified string matches the end of the instance string. |
|
|
|
Equals |
|
Determines whether the instance string and a specified string have the same |
|
|
value. |
GetEnumerator Method required to support the IEnumerator interface (see "Interfaces" later in thischapter).
IndexOf |
|
Reports the index of the first occurrence of a specified character or string |
|
|
within theinstance. |
|
|
|
Insert |
|
Returns a new string with the specified string inserted at the specified |
|
|
position in thecurrent string. |
LastIndexOf
PadLeft
PadRight
Remove
Replace
Split
Reports the index of the last occurrence of a specified character or string within theinstance.
Returns a new string with the characters in this instance right-aligned by padding on the left with spaces or a specified character for a specified total length.
Returns a new string with the characters in this instance left-aligned by padding on the right with spaces or a specified character for a specified total length.
Returns a new string that deletes a specified number of characters from the current instance beginning at a specified position.
Returns a new string that replaces all occurrences of a specified character or string in the current instance, with another character or string.
Identifies the substrings in this instance that are delimited by one or more characters specified in an array, then places the substrings into a string array.
StartsWith |
|
Returns true if the specified string matches the beginning of the instance |
|
|
string. |
|
|
|
Substring |
|
Returns a substring from the instance. |
|
|
|
ToCharArray |
|
Copies the characters in the instance to a character array. |
|
|
|
ToLower |
|
Returns a copy of the instance in lowercase. |
|
|
|
ToUpper |
|
Returns a copy of the instance in uppercase. |
|
|
|
Trim |
|
Returns a copy of the instance with all occurrences of a set of specified |
|
|
characters from the beginning and end removed. |
|
|
|
TrimEnd |
|
Returns a copy of the instance with all occurrences of a set of specified |
|
|
characters at the end removed. |
|
|
|
TrimStart |
|
Returns a copy of the instance with all occurrences of a set of specified |
|
|
characters from the beginning removed. |
Static Methods
Table 9.4 describes many of the static methods of the String class.
|
|
Table 9.4: Static Methods of the String Class |
|
|
|
Method |
|
What It Does |
|
|
|
Compare |
|
Compares two string objects. |
|
||
CompareOrdinal |
|
Compares two string objects without considering the local national |
|
|
language orculture. |
|
|
|
Concat |
|
Creates a new string by concatenating one or more strings. |
|
|
|
Copy |
|
Creates a new instance of a string by copying an existing instance. |
|
|
|
Format |
|
Formats a string using a format specification. See 'Formatting Overview' in |
|
|
online help for more information about format specifications. |
|
|
|
Join |
|
Concatenates a specified string between each element in a string to yield a |
|
|
single concatenated string. |
|
|
|
The StringBuilder Class
As I mentioned earlier in this chapter, instances of the StringBuilder class-as opposed to the String class-are mutable, or dynamically changeable. StringBuilder is located in the System
.Text namespace. As you can see in Table 9.5, it does not have nearly as many members as the String class-but it does have enough to get most jobs done. If you have a situation in which you need to perform many string operations-for example, within a large loop-from a performance viewpoint it probably makes sense to use StringBuilder instances instead of String instances.
|
Table 9.5: Key Instance Members of the StringBuilder Class |
||
|
|
|
|
Member |
|
|
What It Does |
|
|
|
|
Append |
|
|
Method adds |
|
|
|
string |
|
|
|
information to |
|
|
|
the end of the |
|
|
|
current |
|
|
|
StringBuilder |
|
|
|
instance. |
|
|
|
Overloads |
|
|
|
make for some |
|
|
|
flexibility |
|
|
|
regarding the |
|
|
|
kinds of |
|
|
|
objects that can |
|
|
|
beappended (if |
|
|
|
not already |
|
|
|
string, then the |
|
|
|
method |
|
|
|
converts the |
|
|
|
object to be |
|
|
|
appended to a |
|
|
|
|
|
Table 9.5: Key Instance Members of the StringBuilder Class |
||
|
|
|
|
Member |
|
|
What It Does |
|
|
|
|
|
|
|
string |
|
|
|
representation). |
|
|
|
|
AppendFormat |
|
|
Method |
|
|
|
appends a |
|
|
|
formatted |
|
|
|
string to the |
|
|
|
current |
|
|
|
instance (see |
|
|
|
'Formatting |
|
|
|
Over view' in |
|
|
|
online help for |
|
|
|
more |
|
|
|
information |
|
|
|
about format |
|
|
|
specifications). |
|
|
|
|
Capacity |
|
|
Property sets |
|
|
|
or retrieves the |
|
|
|
maximum |
|
|
|
number of |
|
|
|
characters that |
|
|
|
can be stored |
|
|
|
in the memory |
|
|
|
allocated for |
|
|
|
the |
|
|
|
StringBuilder |
|
|
|
instance. |
|
|
|
|
Insert |
|
|
Method inserts |
|
|
|
a string, or |
|
|
|
string |
|
|
|
representation |
|
|
|
of an object, |
|
|
|
into the current |
|
|
|
StringBuilder |
|
|
|
instance at the |
|
|
|
specified |
|
|
|
position. |
|
|
|
|
Length |
|
|
Property gets |
|
|
|
or sets the |
|
|
|
length of the |
|
|
|
instance. |
|
|
|
Setting this to a |
|
|
|
value that is |
|
|
|
less than the |
|
|
|
length of the |
|
|
|
current |
|
|
|
instance |
|
|
|
|
|
Table 9.5: Key Instance Members of the StringBuilder Class |
||
|
|
|
|
Member |
|
|
What It Does |
|
|
|
|
|
|
|
truncates the |
|
|
|
instance. |
|
|
|
|
Remove |
|
|
Method |
|
|
|
removes a |
|
|
|
specified |
|
|
|
number of |
|
|
|
characters from |
|
|
|
the current |
|
|
|
StringBuilder |
|
|
|
instance. |
|
|
|
|
Replace |
|
|
Method |
|
|
|
replaces all |
|
|
|
occurrences of |
|
|
|
a specified |
|
|
|
character in the |
|
|
|
current |
|
|
|
instance (or |
|
|
|
part of the |
|
|
|
current |
|
|
|
instance) with |
|
|
|
a specified |
|
|
|
string. |
|
|
|
|
There are six different overloads of the StringBuilder constructor, designed so that you can create an instance already containing text and-if desired-set the Length and Capacity properties. As you'd suspect, the shortest StringBuilder constructor simply creates an instance without storing any text in it. Listing 9.2 demonstrates creating a StringBuilder instance on the fly. Next, the Append method is used to store the contents of a TextBox in the StringBuilder. The Length property is used to truncate the StringBuilder to four characters. Finally, the StringBuilder is converted to a just plain vanilla string and displayed in a message box.
Listing 9.2: Creating and Truncating a StringBuilder on the Fly
private void btnSB_Click(object sender, System.EventArgs e) { System.Text.StringBuilder theSB = new System.Text.StringBuilder(); theSB.Append (txtSB1.Text);
theSB.Length = 4;
MessageBox.Show (theSB.ToString(), "StringBuilder", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
If you run the code shown in Listing 9.2, first adding some text to the TextBox, you'll see that the text has been appended to the StringBuilder, which is truncated at four characters (Figure 9.3).
Figure 9.3: Text added to the TextBox is appended in the StringBuilder instance.
Let's do another StringBuilder example. Listing 9.3 appends the contents of three TextBoxes into one StringBuilder. The user then enters two characters in a fourth TextBox. All instances of the first character are replaced in the StringBuilder with the second character, and the StringBuilder is then displayed in a multiline TextBox.
Listing 9.3: Appending and Replacing in a StringBuilder
private void btnSB_Click(object sender, System.EventArgs e) { System.Text.StringBuilder theSB = new System.Text.StringBuilder(); theSB.Append (txtSB1.Text);
theSB.Append (txtSB2.Text); theSB.Append (txtSB3.Text); txtDoIt.Text = "";
string str = txtReplace.Text; theSB.Replace (str[0],str[1]); txtDoIt.Text = theSB.ToString();
}
The result of running this code, entering the strings 'A nose ', 'is a nose ', and 'is a nose' in the TextBoxes, and replacing the character 'n' with 'r', is shown in Figure 9.4.
Figure 9.4: The StringBuilder Replace method can be used to replace all instances of a character in a StringBuilder with another character.
Implementing the ToString Method
I can't even start to think how many times in this book so far that I've used an object's ToString method. It's very handy-dandy, and you always know you'll get a string returned with the method-although it's sometimes not entirely clear, until you try, what the string will consist of. (For example, the ToString method of a Form instance returns the value of the
Form's Text property as well as the instance name.) Since Object has a ToString method, and all classes are ultimately derived from Object, you can be sure that any instance in fact has some kind of ToString method.
I've repeated the mantra many times that it's up to you to implement a meaningful ToString method in your own classes. Before we proceed to an implementation example, let's think for a second about what "meaningful" means. Clearly, we'd like a number to be converted to a string representation of the number, so 423.ToString() returns the string "423". It's also reasonable to expect a Boolean value to return a string representation of the value it represents. The expression false.ToString() returns the string "False". With a capital F, it differs from the keyword false used to evaluate a C# Boolean expression, but it is still acceptable.
Simple value types are easy, but more complex objects don't always have a clear string representation. What should ToString return for a Button control? One thing seems fairly consistent-that when there is a Text or Name property for the class, the instance ToString method returns it as part or all of the return value.
To construct a ToString implementation example, let's return for a moment to the abstract Dinosaur class that was used in Chapter 8, "The Life of the Object in C#," to demonstrate polymorphism in its derived classes. Here's the entire class definition from Chapter 8:
public abstract class Dinosaur { public abstract string GetFood();
}
I'll be using the Dinosaur class in the next section to demonstrate implementing an interface, and interface inheritance, so let's redo the base Dinosaur class so that it is no longer abstract, and, while we're at it, let's add a few members, as shown in Listing 9.4.
Listing 9.4: The Base Dinosaur Class
public class Dinosaur
{
private string m_Name; private bool m_EatMeat; public int Length = 0;
public virtual string GetFood(){ return "You are what you eat!";
}
public string Name { get {
return m_Name;
}
set {
m_Name = value;
}
}
public bool EatMeat { get {
return m_EatMeat;
}
set {
m_EatMeat = value;
}