This chapter examines three fundamental elements of C#: data types, literals, and variables. In general, the types of data that a language provides define the kinds of problems to which the language can be applied. As you might expect, C# offers a rich set of built-in data types, which makes C# suitable for a wide range of applications. You can create variables of any of these types, and you can specify constants of each type, which in the language of C# are called literals.
Why Data Types Are Important
Data types are especially important in C# because it is a strongly typed language. This means that, as a general rule, all operations are type-checked by the compiler for type compatibility. Illegal operations will not be compiled. Thus, strong type-checking helps prevent errors and enhances reliability. To enable strong type-checking, all variables, expressions, and values have a type. There is no concept of a “typeless” variable, for example. Furthermore, a value’s type determines what operations are allowed on it. An operation allowed on one type might not be allowed on another.
Note. C# 4.0 adds a new data type called dynamic, which causes type checking to be deferred until runtime, rather than occurring at compile time. Thus, the dynamic type is an exception to C#’s normal compile-time type checking. The dynamic type is discussed in Chapter 17.
C#’s Value Types
C# contains two general categories of built-in data types: value types and reference types. The difference between the two types is what a variable contains. For a value type, a variable holds an actual value, such 3.1416 or 212. For a reference type, a variable holds a reference to the value. The most commonly used reference type is the class, and a discussion of classes and reference types is deferred until later in this book. The value types are described here.
At the core of C# are the 13 value types shown down. Collectively, these are
referred to as the simple types. They are called simple types because they consist of a single value. (In other words, they are not a composite of two or more values.) They form the foundation of C#’s type system, providing the basic, low-level data elements upon which a program operates. The simple types are also sometimes referred to as primitive types.
Bool Represents true/false values
Byte 8-bit unsigned integer
Decimal Numeric type for financial calculations
Double Double-precision floating point
Float Single-precision floating point
Long Long integer
Sbyte 8-bit signed integer
Short Short integer
Uint An unsigned integer
Ulong An unsigned long integer
Ushort An unsigned short integer
C# strictly specifies a range and behavior for each value type. Because of portability requirements, C# is uncompromising on this account. For example, an int is the same in all execution environments. There is no need to rewrite code to fit a specific platform. Although strictly specifying the size of the value types may cause a small loss of performance in some environments, it is necessary in order to achieve portability.
Note. In addition to the simple types, C# defines three other categories of value types. These are enumerations, structures, and nullable types, all of which are described later in this book.
C# defines nine integer types: char, byte, sbyte, short, ushort, int, uint, long, and ulong. However, the char type is primarily used for representing characters, and it is discussed later in this chapter.