Value types are the built-in types provided by C# that you can use to store simple values and combine to build your own types called classes. Table 1-1 describes some of the common types you will encounter in C#, as well as their memory allocation requirements. You will find all of these simple value types on the stack when they are used by themselves, without being in a class. It is important to realize that all the types listed in Table 1-1 are aliases; for example, System.int32 is the real name for int.
|
Symbolic Name |
Description |
|---|---|
|
sbyte |
8-bit signed integer |
|
short |
16-bit signed integer |
|
int |
32-bit signed integer |
|
long |
64-bit signed integer |
|
byte |
8-bit unsigned integer |
|
ushort |
16-bit unsigned integer |
|
uint |
32-bit unsigned integer |
|
ulong |
64-bit unsigned integer |
|
float |
Single-precision floating point |
|
double |
Double-precision floating point |
|
bool |
True or false |
|
char |
Unicode character, 16 bytes |
|
decimal |
Precise decimal with 28 digits |
| Note |
Since all value types inherit from System.Object, you will always see the GetHashCode, ToString, CompareTo, Equals, GetType, and GetTypeCode methods available to value types. Their exact functionality will be described in later chapters. |
The following example shows common value types.
using System; namespace Client.Chapter_1___Common_Type_System { class ValueType { static void Main(string[] args) { //Declares an instance of a value type. These objects will be //placed on the stack. All value types inherit from //System.ValueType, which in turn inherits from //System.Object. Common value types include all basic types //such as int, long, struct, and enum. int MyInt = 12345; long MyLong = MyInt; short MyShort = (short)MyInt; } } }
A bool is a variable that holds one of two values, true or false, and consumes 1 byte. In C#, a bool is a true type, not just an integer that stores a zero for false and a nonzero value for true. Therefore, a bool cannot be converted to a numeric type. The following shows an example of using a bool type.
using System;
namespace Client.Chapter_1___Common_Type_System
{
class UsingBool
{
static void Main(string[] args)
{
bool MyBool = false;
//Use bool in if statement
if (MyBool)
{
//Writes true to console
Console.WriteLine(MyBool);
}
else
{
//Writes false to console
Console.WriteLine(MyBool);
}
}
}
}
The int keyword is used to store integer values or whole numbers. When an integer is defined, the compiler will reserve enough memory to hold an integer in C#, which is 4 bytes. One byte is large enough to hold 8 bits (or 8 ones or zeros).
In C#, the valid ranges of value for an int are −2,147,483,648 to +2,147,483,648. In addition to the int type, there are several other types of varying size that can be used to store whole numbers. Table 1-2 shows these types, the smallest and largest values each can hold, and the memory they require.
|
Type |
Smallest Value |
Largest Value |
Memory |
|---|---|---|---|
|
short |
−32,768 |
32,768 |
2 bytes – 16 bits |
|
ushort |
0 |
65,536 |
2 bytes – 16 bits |
|
int |
−2,147,483,648 |
2,147,483,648 |
4 bytes – 32 bits |
|
uint |
0 |
4,294,967,296 |
4 bytes – 32 bits |
|
long |
−9,223,372,036,854,775,808 |
9,223,372,036,854,775,808 |
8 bytes – 64 bits |
|
ulong |
0 |
18,446,744,073,709,551,616 |
8 bytes – 64 bits |
A feature of C# is that it protects against placing a value in a type that is beyond the range that it can hold. This is done by using the keyword checked, which will cause an OverflowException to occur at runtime if a type is assigned a value beyond its limits.
checked (expression) or (statement block)
The unchecked statement disables this functionality, but it is rarely useful unless you want to force an assignment of data that is beyond a type's accepted range.
unchecked (expression) or (statement block)
The following shows an example of using integers.
using System; namespace Client.Chapter_1___Common_Type_System { class UsingIntegers { static void Main(string[] args) { int MyInt = 12345; long MyLong = MyInt; } public long My2ndFunction(long myLong) { //Creates a try block try { //If the value calculated for MyLong exceeds the maximum //value for a long, you will get an OverflowException long c = checked(myLong * 500); } catch (OverflowException e) { Console.WriteLine(e); } return 0; } } }
C# provides support for Unicode char types. A char is an integer value that is an interpretation of an integer type that has a defined value based on the Unicode standard. You may use char types to store a single character or in an array to store an entire string. However, the easiest way to store a string is to use the built-in string class for nonmutable strings, or maybe a StringBuilder class if the string needs to be mutable.
In C#, char types reserve 2 bytes of memory and expect a Unicode string as opposed to an ASCII (American Standard Code Information Interchange) string, which C++ expects in a char type. C# char types are similar to C++'s wchar_t types.
If you need to do manipulations from Unicode strings to ASCII, you may wish to examine the System.Runtime.InteropServices.Marshal class. For example, you can take a managed string and move it to an array of ASCII char types by doing the following:
sbyte* pServer = (sbyte*)Marshal.StringToCoTaskMemAnsi("My Managed String");
The following example shows how to use char types.
using System;
namespace Client.Chapter_1___Common_Type_System
{
class UsingChar
{
static void Main(string[] args)
{
//Declares and initializes a char to the value of A
char MyChar = 'A';
//Here the Unicode value of 65 is cast to a char, which is A
MyChar = (char)65;
char[] MyChar2 = { 'H', 'e', 'l', 'l', 'o', '\0' };
char[] MyChar3 = new char[5];
//Fills a char array
MyChar3[0] = 'H';
MyChar3[1] = 'e';
MyChar3[2] = 'l';
MyChar3[3] = 'l';
MyChar3[4] = 'o';
MyChar3[5] = '\0';
}
}
}
In C++, Microsoft provided a string class in the Microsoft Foundation Classes (MFC), and the Standard Template Library (STL) provided one as well. It was so helpful to developers that a string class was built into C# to let programmers avoid the common use of string pointers and char arrays, as well as needing to depend on an extension. C#'s explicit type called string can be used to store an entire string. It is important to realize that this type is an alias for System.String.
| Caution |
Keep in mind that the string type is only used for nonmutable strings. If you plan to use a string and make a lot of changes to it, you will want to examine the System.Text.StringBuilder class. This will save your application many performance woes. For more information, see the Microsoft Knowledge Base article, "PRB: High CPU Utilization in Web Service or Web Form" (http://support.microsoft.com/default.aspx?scid=kb;en-us;307340). |
The great thing about having a string type is the built-in methods supported by this type. These methods, listed in Table 1-3, allow you to manipulate the string.
|
Method Name |
Description |
|---|---|
|
CompareTo |
Compares the current instance with a specified object |
|
CopyTo |
Copies a specific number of characters to a specific position in a Unicode array |
|
EndsWith |
Determines if the end of this string matches a given string |
|
Remove |
Deletes characters from this string, given a specific index to start |
|
Replace |
Replaces all characters that match a specified string |
|
Split |
Identifies substrings within a string |
|
StartsWith |
Determines if a given string matches the beginning of the current string |
|
Substring |
Returns a substring from the given string |
|
ToCharArray |
Returns a Unicode char array |
|
ToLower |
Returns an all lowercase string |
|
ToUpper |
Returns an all uppercase string |
|
Trim |
Removes all instances of a specified string from the beginning or end of the current string |
|
TrimEnd |
Removes characters from the end of the current string |
|
TrimStart |
Removes characters from the beginning of the current string |
Escape characters are used in char and string types to tell the compiler to ignore the normal meaning of the next character and to recognize some special functionality or special meaning. The escape character in C# is the backslash (\). This escape character is used in conjunction with the characters listed in Table 1-4.
|
Escape Character |
Meaning |
Hex Value |
|---|---|---|
|
\' |
Single quote |
0x0027 |
|
\" |
Double quotes |
0x0022 |
|
\\ |
Backslash |
0x005C |
|
\0 |
Null termination |
0x0000 |
|
\a |
Alert |
0x0007 |
|
\b |
Backspace |
0x0008 |
|
\f |
Form feed |
0x000C |
|
\n |
New line |
0x000A |
|
\r |
Carriage return |
0x000D |
|
\t |
Horizontal tab |
0x0009 |
|
\v |
Vertical tab |
0x000B |
A feature of C# that allows you to avoid using escape characters in some cases is the @ symbol syntax. A string object could use the following syntax to assign the exact string, without using the \\ escape character.
string MyString = @"c:\Program Files\My Program\strings.exe";
| Caution |
You must still use the escape sequence for double quotation marks! For example, use string MyString = " \"To Be or Not To Be, That Is The Question\" ";. |
The following example shows the use of escape characters.
using System; namespace Client.Chapter_1___Common_Type_System { class EscapeCharacters { static void Main(string[] args) { char MyChar='\0'; //The @ symbol tells C# to take the string literally string MyString=@"C:\MyFiles"; string MYString2="c:\\Program Files"; //Even with the @ symbol, you must still escape quotation marks string MyString3=" \"To Be or Not To Be, That Is The Question\" "; } } }
Since integer data types can store only whole numbers, there must be a way to store very large fractional numbers. C# provides the float, double, and decimal types to handle large fractional numbers. A float is 4 bytes, and a double uses 8 bytes. The decimal type is a new feature to C#. It is used for calculations in which rounding errors caused by floating points are unacceptable. The decimal type holds 28 digits and the position of the decimal point. Table 1-5 shows the lowest and highest values for these types.
|
Type |
Lowest |
Highest |
|---|---|---|
|
float |
+/−1.5 × 10^-45 |
+/−3.4 × 10^38 |
|
double |
+/−5.0 × 10^-324 |
+/−1.7 × 10^308 |
|
decimal |
+/−1.0 × 10^-28 |
−7.9 × 10^28 |
The following example shows the use of float, double, and decimal types.
using System; namespace Client.Chapter_1___Common_Type_System { class UsingFloats { static void Main(string[] args) { float MyFloat = 3.281f; double MyDouble = 5E-02; } } } using System; namespace Client.Chapter_1___Common_Type_System { class UsingDecimals { static void Main(string[] args) { decimal MyDecimal = 3.50m; } } }