C# - Data Types

The C# typing system contains the following categories:

  • Value types
  • Reference types
  • Pointer types

Variables of the value types store data, while those of the reference types store references to the actual data. Reference types are also referred to as objects. Pointer types can be used only in unsafe mode.

It is possible to convert a value type to a reference type and vice versa, by using boxing and unboxing.

Value Types

A variable of a value type always contains a value of that type. The assignment to a variable of a value type creates a copy of the assigned value, while the assignment to a variable of a reference type creates a copy of the reference but not of the referenced object.

All value types are derived implicitly from the Object class.

Each value type has an implicit default constructor that initializes the default value of that type.

At the core of C# are the 13 value types. 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.

Integer Types

C# supports eight predefined integer types, shown in the following table.

NameCTS TypeDescriptionRange (min:max)
sbyte System.SByte 8-bit signed integer -128 to 127
short System.Int16 16-bit signed integer -32768 to 32767
int System.Int32 32-bit signed integer -2147483648 to 2147483647
long System.Int64 64-bit signed integer -9223372036854775808 to 9223372036854775807
byte System.Byte 8-bit unsigned integer 0 to 255
ushort System.UInt16 16-bit unsigned integer 0 to 65535
uint System.UInt32 32-bit unsigned integer 0 to 4294967295
ulong System.UInt64 64-bit unsigned integer 0 to 18446744073709551615

Floating-Point Types

The floating-point types can represent numbers that have fractional components. There are two kinds of floating-point types, float and double, which represent single- and double precision numbers, respectively.

NameCTS TypeDescriptionSignificant FiguresRange (Approximate)
float System.Single 32-bit, single-precision floating point 7 ±1.5 × 10245 to ±3.4 × 1038
double System.Double 64-bit, double-precision floating point 15/16 ±5.0 × 102324 to ±1.7 × 10308

The Decimal Type

NameCTS TypeDescriptionSignificant FiguresRange (Approximate)
decimal System.Decimal 128-bit, high-precision decimal notation 28 ±1.0 × 10228 to ± 7.9 × 1028

One of the great things about the CTS and C# is the provision of a dedicated decimal type for financial calculations. How you use the 28 digits that the decimal type provides is up to you. In other words, you can track smaller dollar amounts with greater accuracy for cents or larger dollar amounts with more rounding in the fractional portion. Bear in mind, however, that decimal is not implemented under the hood as a primitive type, so using decimal has a performance effect on your calculations

To specify that your number is a decimal type rather than a double, float, or an integer, you can append the M (or m) character to the value, as shown here:

decimal d = 18.30M;

The Boolean Type

The C# bool type is used to contain Boolean values of either true or false.

NameCTS TypeDescriptionSignificant FiguresRange (Approximate)
bool System.Boolean Represents true or false NA true or false

The Character Type

The char keyword is used to declare an instance of the System.Char structure that the .NET Framework uses to represent a Unicode character. The value of a Char object is a 16-bit numeric (ordinal) value.

NameCTS TypeValues
char System.Char Represents a single 16-bit (Unicode) character

Reference Types

There are two kinds of types in C#: reference types and value types. Variables of reference types store references to their data (objects), while variables of value types directly contain their data. With reference types, two variables can reference the same object; therefore, operations on one variable can affect the object referenced by the other variable. With value types, each variable has its own copy of the data, and it is not possible for operations on one variable to affect the other (except in the case of ref and out parameter variables, see ref (C# Reference) and out parameter modifier

The following keywords are used to declare reference types:

  • class
  • interface
  • delegate

C# also provides the following built-in reference types:

  • dynamic
  • object
  • string