A C# string represents an immutable sequence of characters, and aliases the System.String class. Strings have comparison, appending, inserting, conversion, copying, formatting, indexing, joining, splitting, padding, trimming, removing, replacing, and searching methods. The compiler converts addition (+) operations on operands, in which the left operand is a string to Concat( ) methods (assuming it can't fold the concatenation together directly at compile time), and also preevaluates and interns string constants where possible (see Chapter 6 later in this chapter).
Although System.String is a reference type, the = = operator is overloaded, so you can easily compare two strings by value, as follows:
string a = "abracadabra"; string b = "abracadabra"; Console.WriteLine(a= =b); // Prints "True"
Strings are immutable, which means they can't be modified after creation. Consequently, many of the methods that initially appear to modify a string actually create a new string:
string a = "Heat"; string b = a.Insert(3, "r") Console.WriteLine(b); // Prints Heart
If you need a mutable string, see the StringBuilder class, discussed later in this chapter.
In addition, the immutability of strings enables all strings in an application to be interned. Interning is the process in which all the constant strings in an application are stored in a common place and any duplicate strings are eliminated. This saves space at runtime but creates the possibility that multiple string references will point to the same location in memory. This can be the source of unexpected results when comparing two constant strings, as follows:
string a = "hello"; string b = "hello"; Console.WriteLine(a = = b); // True for String only Console.WriteLine(a.Equals(b)); // True for all objects Console.WriteLine((object)a = = (object)b); // True!!
The Format( ) method provides a convenient way to build strings that make use of embedded parameters. Parameters in such strings can be of any type, including both predefined and user-defined types.
The String.Format( ) method takes a format-specification string, followed by a variable number of parameters. The format-specification string defines the template for the string; the position and format of each parameter within the string is specified by a format specifier for each of its parameters.
The syntax of a format specifier looks like this:
{ParamIndex[,MinWidth][:FormatString]}
It has the following parameters:
This is the zero-based index of the parameter to be formatted. This number specifies a position in the parameter list that follows the format-specification string.
This is the minimum number of characters required for the string representation of the parameter, to be padded by spaces if necessary (a negative number is left-justified, a positive number is right-justified). If not specified, the string representation consumes the minimum number of characters possible.
This is passed to the ToString( ) method on IFormattable to construct the string if the parameter represents an object that implements IFormattable. If not, the ToString( ) method on System.Object is used to construct the string.
|
In the following example, we embed string specifiers for the integer account variable i (parameter 0 in the parameter list), and the decimal cash variable m (parameter 1 in the parameter list, with C = currency) in the format-specification string:
Account {0} has {1:C}
The parameters themselves are listed immediately following the string template:
using System; class TestFormatting { static void Main( ) { int i = 2; decimal m = 42.73m; string s = String.Format("Account {0} has {1:C}.", i, m); Console.WriteLine(s); // Prints "Account 2 has $42.73" } }
Consistent with all other indexing in the CLR, the characters in a string are accessed with a zero-based index:
using System; class TestIndexing { static void Main( ) { string s = "Going down?"; for (int i=0; i<s.Length; i++) Console.WriteLine(s[i]); // Prints s vertically } }
Strings can be converted between different character encodings using the Encoding type. The Encoding type can't be created directly, but the ASCII, Unicode, UTF7, UTF8, and BigEndianUnicode static properties on the Encoding type return correctly constructed instances.
Here is an example that converts an array of bytes into a string using the ASCII encoding:
using System; using System.Text; class TestEncoding { static void Main( ) { byte[ ] ba = new byte[ ] { 67, 35, 32, 105, 115, 32, 67, 79, 79, 76, 33 }; string s = Encoding.ASCII.GetString(ba); Console.WriteLine(s); } }