C#: Data Types

A type is some general scheme of value (data). A variable is a piece of memory that can contain different values (as opposed to a constant, which can only contain one value). The range of possible values for a variable is determined by its type.

Predefined Types or Built-in Types

Predefined types are types that are directly supported by the compiler. The predefined types in C# include:

  • Value types
    • Numeric
      • Signed integers: sbyte, short, int, long
      • Unsigned integers: byte, ushort, uint, ulong
      • Real numbers: float, double, decimal
    • Logical type: bool
    • Character type: char
  • Reference types
    • String type: string
    • Object type: object

The predefined types are aliased in the framework in the System. Predefined types, with the exception of the decimal type, are called primitive types in the CLR (Common Language Runtime), because they are supported by instructions at the processor level.

Custom Types

Custom types – types introduced by the application developer (classes).

Types contain data members or fields and function members or methods.

Instantiation and constructors. Data is created by instantiating the type. Instances of predefined types are created directly using literals (12, "Hellow world"). Instances of user-defined types are created using the new operator. Immediately after the new operator creates an object, the object’s constructor is run and initialization takes place. A constructor is a normal method, except that its name and return type are the same as the name of the type being created.

Instance members and static members. Type members that interact with an instance of a type are called instance members. By default, members are just instance members. Type members that do not interact with an instance of the type, but rather with the type itself, should be marked as static. If a class (type) contains only static members, it is a static class; An instance of such a class cannot be created.


Compatible types can be converted to each other. This always creates a new value from an existing one. The transformation can be implicit and explicit. The implicit conversion happens automatically, while the explicit one requires an explicit cast. An implicit conversion is only possible when the compiler can guarantee that no data loss will occur. Otherwise, an explicit cast is required.

Value Types and Reference Types

Types in C# are divided into value types and reference types. Value types include most of the built-in types, namely: all numeric types (numeric), the char type (character), the bool type (boolean), as well as custom struct (structures) and enum (enumerations) types. Reference types include all classes (class), arrays (array), delegates (delegate) and interfaces (interface).

The key difference between value types and reference types is how they are stored in memory. The content of a variable or constant of one of the value types is just a value. When assigning an instance of a value type, the instance is always copied. The reference type is more complex: it consists of two parts – an object and a reference to this object. The content of a reference type variable or constant is a reference to an object, which in turn contains a value. When you assign a reference type to a variable, the reference is copied, but not the object itself. This makes it possible for multiple variables to refer to the same object, which is not possible for value types.

A reference variable can be assigned the literal null, which means that the reference does not point to an object. Attempting to access members of a non-existent object will cause a runtime error. Value types cannot have null as their value (non-existent value), and attempting to do so will result in a compile-time error.