only for RuBoard - do not distribute or recompile Previous Section Next Section

3.3 Strings

C# offers a wide range of string-handling features. Support is provided for both mutable and immutable strings, extensible string formatting, locale-aware string comparisons, and multiple string encoding systems.

This section introduces and demonstrates the most common types you'll use when working with strings. Unless otherwise stated, the types mentioned in this section all exist in the System or System.Text namespaces.

3.3.1 String Class

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 + operations on operands where the left operand is a string to Concat methods and preevaluates and interns string constants wherever possible.

3.3.2 Immutability of Strings

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.

3.3.3 String Interning

In addition, the immutability of strings enable all strings in an application to be interned. Interning describes the process whereby 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 at the same spot 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.ReferenceEquals(a, b)); // True!!

3.3.4 Formatting Strings

The Format method provides a convenient way to build strings that embed string representations of a variable number of parameters. Each parameter can be of any type, including both predefined types and user-defined types.

The Format method takes a format-specification string and a variable number of parameters. The format-specification string defines the template for the string and includes format specifications for each of the parameters. The syntax of a format specifier looks like this:

{ParamIndex[,MinWidth][:FormatString]}
ParamIndex

The zero-based index of the parameter to be formatted.

MinWidth

The minimum number of characters for the string representation of the parameter, to be padded by spaces if necessary (negative is left-justified, positive is right-justified).

FormatString

If the parameter represents an object that implements IFormattable, the FormatString is passed to the ToString method on IFormattable to construct the string. If not, the ToString method on Object is used to construct the string.

All of the common types (int, string, DateTime, etc.) implement IFormattable. A table of the numeric and picture format specifiers supported by the common predefined types is provided in Appendix C.

In the following example, we embed a basic string representation of the account variable (param 0) and a monetary string representation of the cash variable (param 1, C=Currency):

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"
  }
}

3.3.5 Indexing Strings

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
  }
}

3.3.6 Encoding Strings

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);
  }
} 

3.3.7 StringBuilder Class

The StringBuilder class is used to represent mutable strings. It starts at a predefined size (16 characters by default) and grows dynamically as more string data is added. It can either grow unbounded or up to a configurable maximum. For example:

using System;
using System.Text;
class TestStringBuilder {
  static void Main(  ) {
    StringBuilder sb = new StringBuilder("Hello, ");
    sb.Append("World?");
    sb[12] = '!';
    Console.WriteLine(sb); // Hello, World!
  }
}
only for RuBoard - do not distribute or recompile Previous Section Next Section