The fundamental types discussed so far are numeric types. C# includes some additional types as well: bool, char, and string.
Boolean Type (bool)
Another C# primitive is a Boolean or conditional type, bool, which represents true or false in conditional statements and expressions. Allowable values are the keywords TRue and false. The BCL name for bool is System.Boolean. The literal values for a Boolean use the keywords true and false. For example, in order to compare two strings in a case-insensitive manner, you call the string.Compare() method and pass a bool literal of true (see Listing 2.8).
Listing 2.8. A Case-Insensitive Comparison of Two Strings
In this case, you make a case-insensitive comparison of the contents of the variable option with the literal text /Help and assign the result to comparison.
Although theoretically a single bit could hold the value of a Boolean, the size of bool is a byte.
Character Type (char)
A char type represents 16-bit characters whose set of possible values corresponds to the Unicode character set. Technically, a char is the same size as a 16-bit unsigned integer (ushort) with values between 0 and 65,535. However, char is a unique type in C# and code should treat it as such.
The BCL name for char is System.Char.
To enter a literal character type, place the character within single quotes, as in 'A'. Allowable characters comprise the full range of keyboard characters, including letters, numbers, and special symbols.
Some characters cannot be placed directly into the source code and instead require special handling. These characters are prefixed with a backslash (\) followed by a special character code. In combination, the backslash and special character code are an escape sequence. For example, '\n' represents a newline, and '\t' represents a tab. Since a backslash indicates the beginning of an escape sequence, it can no longer identify a simple backslash; instead, you need to use '\\' to represent a single backslash character.
Listing 2.9 writes out one single quote because the character represented by \' corresponds to a single quote.
Listing 2.9. Displaying a Single Quote Using an Escape Sequence
In addition to showing the escape sequence, Table 2.4 includes the Unicode representation of characters.
You can represent any character using Unicode encoding. To do so, prefix the Unicode value with \u. You represent Unicode characters in hexadecimal notation. The letter A, for example, is the hexadecimal value 0x41; Listing 2.10 uses Unicode characters to display a smiley face (:)), and Output 2.8 shows the results.
Listing 2.10. Using Unicode Encoding to Display a Smiley Face
The fundamental string type in C# is the data type string, whose BCL name is System.String. The string includes some special characteristics that may be unexpected to developers familiar with other programming languages. The characteristics include a string verbatim prefix character, @, and the fact that a string is immutable.
You can enter a literal string into code by placing the text in double quotes ("), as you saw in the HelloWorld program. Strings are composed of characters, and because of this, escape sequences can be embedded within a string.
In Listing 2.11, for example, two lines of text are displayed. However, instead of using System.Console.WriteLine(), the code listing shows System.Console.Write() with the newline character, \n. Output 2.9 shows the results.
Listing 2.11. Using the \n Character to Insert a Newline
The escape sequence for double quotes differentiates the printed double quotes from the double quotes that define the beginning and end of the string.
In C#, you can use the @ symbol in front of a string to signify that a backslash should not be interpreted as the beginning of an escape sequence. The resulting verbatim string literal does not reinterpret just the backslash character. Whitespace is also taken verbatim when using the @ string syntax. The triangle in Listing 2.12, for example, appears in the console exactly as typed, including the backslashes, newlines, and indentation. Output 2.10 shows the results.
Listing 2.12. Displaying a Triangle Using a Verbatim String Literal
Without the @ character, this code would not even compile. In fact, even if you changed the shape to a square, eliminating the backslashes, the code would still not compile because a newline cannot be placed directly within a string that is not prefaced with the @ symbol.
The only escape sequence the verbatim string does support is "", which signifies double quotes and does not terminate the string.
If the same literal string appears within an assembly multiple times, the compiler will define the string only once within the assembly and all variables will point to the single string literal. That way, if the same string literal containing thousands of characters was placed multiple times into the code, the resulting assembly would reflect the size of only one of them.
The string type, like the System.Console type, includes several methods. There are methods, for example, for formatting, concatenating, and comparing strings.
The Format() method in Table 2.5 behaves exactly like the Console.Write() and Console.WriteLine() methods, except that instead of displaying the result in the console window, string.Format() returns the result.
All of these methods are static. This means that, to call the method, it is necessary to prefix the method name with the type that contains the method. Some of the methods in the string class, however, are instance methods. Instead of prefixing the method with the type, instance methods use the variable name (or some other reference to an instance). Table 2.6 shows a few of these methods, along with an example.
To determine the length of a string you use a string member called Length. This particular member is called a read-only property. As such, it can't be set, nor does calling it require any parameters. Listing 2.13 demonstrates how to use the Length property, and Output 2.11 shows the results.
Listing 2.13. Using string's Length Member
The length for a string cannot be set directly; it is calculated from the number of characters in the string. Furthermore, the length of a string cannot change because a string is immutable.
Strings Are Immutable
The key characteristic of the string type is the fact that it is immutable. A string variable can be assigned an entirely new value, but for performance reasons, there is no facility for modifying the contents of a string. It is not possible, therefore, to convert a string to all uppercase letters. It is trivial to create a new string that is composed of an uppercase version of the old string, but the old string is not modified in the process. Consider Listing 2.14 as an example.
Listing 2.14. Error; string Is Immutable
Output 2.12 shows the results of Listing 2.14.
At a glance, it would appear that text.ToUpper() should convert the characters within text to uppercase. However, strings are immutable and, therefore, text.ToUpper() will make no such modification. Instead, text.ToUpper() returns a new string that needs to be saved into a variable or passed to System.Console.WriteLine() directly. The corrected code is shown in Listing 2.15, and its output is shown in Output 2.13.
Listing 2.15. Working with Strings
If the immutability of a string is ignored, mistakes similar to those shown in Listing 2.14 can occur with other string methods as well.
To actually change the value in text, assign the value from ToUpper() back into text, as in the following:
text = text.ToUpper();
If considerable string modification is needed, such as when constructing a long string in multiple steps, you should use the data type System.Text.StringBuilder rather than string. System.Text.StringBuilder includes methods such as Append(), AppendFormat(), Insert(), Remove(), and Replace(), some of which also appear on string. The key difference, however, is that on System.Text.StringBuilder, these methods will modify the data in the variable, and will not simply return a new string.