2.5 Predefined Types

This section explains each of C#'s predefined types:

  • Value types

    Integer, signed (sbyte, short, int, long)
    Integer, unsigned (byte, ushort, uint, ulong)
    Floating-point (float, decimal, double)
  • Reference types

    Object
    String

All of these types alias types found in the System namespace. For example, there is only a syntactic difference between these two statements:

int i = 5;
System.Int32 i = 5;

2.5.1 Integral Types

C# type

System type

Size

Signed

sbyte

System.SByte

1 byte

yes

short

System.Int16

2 bytes

yes

int

System.Int32

4 bytes

yes

long

System.Int64

8 bytes

yes

byte

System.Byte

1 byte

no

ushort

System.UInt16

2 bytes

no

uint

System.UInt32

4 bytes

no

ulong

System.UInt64

8 bytes

no

For unsigned integers that are n bits wide, possible values range from 0 to 2n-1. For signed integers that are n bits wide, their possible values range from -2n-1 to 2n-1-1. Integer literals can use either decimal or hexadecimal notation:

int x = 5;
ulong y = 0x1234AF; // prefix with 0x for hexadecimal

When an integral literal is valid for several possible integral types, the default type chosen goes in this order: int, uint, long, and ulong. The following suffixes may be used to explicitly specify the chosen type:

U

uint or ulong

L

long or ulong

U

ulong

2.5.1.1 Integral conversions

An implicit conversion between integral types is permitted when the type to convert to contains every possible value of the type to convert from. Otherwise an explicit conversion is required. For instance, you can implicitly convert an int to a long, but must explicitly convert an int to a short:

int x = 123456;
long y = x; // implicit, no information lost
short z = (short)x; // explicit, truncates x

2.5.2 Floating-Point Types

C# type

System type

Size

float

System.Single

4 Bytes

double

System.Double

8 Bytes

A float can hold values from approximately ±1.5 x 10-45 to approximately ±3.4 x 1038 with 7 significant figures.

A double can hold values from approximately ±5.0 x 10-324 to approximately ±1.7 x 10308 with 15-16 significant figures.

Floating-point types can hold the special values +0, -0, +, -, and NaN (not a number), which represent the outcome of mathematical operations such as division by zero. float and double implement the specification of the IEEE 754 format types, supported by almost all processors, and defined by the IEEE at http://www.ieee.org.

Floating-point literals can use decimal or exponential notation. A float literal requires the suffix f or F. A double literal may choose to add the suffix d or D.

float x = 9.81f;
double y = 7E-02; // 0.07
2.5.2.1 Floating-point conversions

An implicit conversion from a float to a double loses no information and is permitted, but not vice versa. An implicit conversion from an int, uint, and long to a float, and from a long to a double is allowed, for readability:

int strength = 2;
int offset = 3;
float x = 9.53f * strength - offset;

If this example uses larger values, precision may be lost. However, the possible range of values is not truncated, since both a float and a double's lowest and highest possible values exceed an int, uint, or long's lowest or highest value. All other conversions between integral and floating-point types must be explicit:

float x = 3.53f;
int offset = (int)x;

2.5.3 Decimal Type

The decimal type can hold values from ±1.0 x 10-28 to approximately ±7.9 x 1028 with 28-29 significant figures.

The decimal type holds 28 digits and the position of the decimal point on those digits. Unlike a floating-point value, it has more precision, but a smaller range. It is typically useful in financial calculations, in which the combination of its high precision and the ability to store a base10 number without rounding errors is very valuable. The number 0.1, for instance, is represented exactly with a decimal, but as a recurring binary number with a floating-point type. There is no concept of +0, -0, +, -, and NaN for a decimal.

A decimal literal requires the suffix m or M.

decimal x = 80603.454327m; // holds exact value
2.5.3.1 Decimal conversions

An implicit conversion from all integral types to a decimal type is permitted because a decimal type can represent every possible integer value. A conversion from a decimal to floating type or vice versa requires an explicit conversion, since floating-point types have a bigger range than a decimal, and a decimal has more precision than a floating-point type.

2.5.4 Char Type

C# type

System type

Size

char

System.Char

2 Bytes

The char type represents a Unicode character. A char literal consists of either a character, Unicode format, or escape character enclosed in single quote marks:

`A' // simple character
`\u0041' // Unicode
`\x0041' // unsigned short hexadecimal
`\n' // escape sequence character

Table 2-1 lists the escape sequence characters.

Table 2-1. Escape sequence characters

Char

Meaning

Value

\'

Single quote

0x0027

\"

Double quote

0x0022

\\

Backslash

0x005C

\0

Null

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

2.5.4.1 Char conversions

An implicit conversion from a char to most numeric types worksit's dependent upon whether the numeric type can accommodate an unsigned short. If it cannot, an explicit conversion is required.

2.5.5 Bool Type

C# type

System type

Size

bool

System.Boolean

1 Byte / 2Byte

The bool type is a logical value that can be assigned the literal true or false.

Although a boolean value requires only one bit (0 or 1), it occupies one byte of storage, since this is the minimum chunk that addressing on most processor architectures can work with. Each element in a boolean array uses two bytes of memory.

2.5.5.1 Bool conversions

No conversions can be made from booleans to numeric types or vice versa.

2.5.6 Object Type

C# type

System type

Size

object

System.Object

0 byte/8 byte overhead

The object class is the ultimate base type for both value types and reference types. Value types have no storage overhead from an object. Reference types, which are stored on the heap, intrinsically require an overhead. In the .NET runtime, a reference-type instance has an eight-byte overhead, which stores the object's type, as well as temporary information such as its synchronization lock state or whether it has been fixed from movement by the garbage collector. Note that each reference to a reference-type instance uses four bytes of storage.

For more information about the System.Object type, see Chapter 26.

2.5.7 String Type

C# type

System type

Size

string

System.String

20 bytes minimum

The C# string represents an immutable sequence of Unicode characters, and aliases the System.String class (see Chapter 26).

Although string is a class, its use is so ubiquitous in programming that it is given special privileges by both the C# compiler and .NET runtime.

Unlike other classes, a new instance can be created using a string literal:

string a = "Heat";

Strings can also be created with verbatim string literals. Verbatim string literals start with @, and indicate that the string should be used verbatim, even if it spans multiple lines or includes escape characters, i.e. "\". In this example, the pairs a1 and a2 represent the same string, and the pairs b1 and b2 represent the same string:

string a1 = "\\\\server\\fileshare\\helloworld.cs";
string a2 = @"\\server\fileshare\helloworld.cs";
Console.WriteLine(a1=  =a2); // Prints "True"

string b1 = "First Line\r\nSecond Line";
string b2 = @"First Line
Second Line";
Console.WriteLine(b1=  =b2); // Prints "True"


    Part II: Programming with the .NET Framework
    Part IV: API Quick Reference
     
    ASPTreeView.com
     
    Evaluation has ЅёґОФЗУЪЗexpired.
    Info...