C# Data Types

Data types in C# define the kind of data a variable can hold and the operations that can be performed on it. Understanding data types is fundamental to writing efficient and correct C# code. C# provides a rich set of built-in data types, categorized into value types and reference types.

Value Types

Value types directly contain their data. When you assign a value type variable to another, the value is copied. Common value types include:

Numeric Types

These types represent numbers.

Type Description Range Default Value
sbyte 8-bit signed integer -128 to 127 0
byte 8-bit unsigned integer 0 to 255 0
short 16-bit signed integer -32,768 to 32,767 0
ushort 16-bit unsigned integer 0 to 65,535 0
int 32-bit signed integer -2,147,483,648 to 2,147,483,647 0
uint 32-bit unsigned integer 0 to 4,294,967,295 0
long 64-bit signed integer -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 0L
ulong 64-bit unsigned integer 0 to 18,446,744,073,709,551,615 0UL
float Single-precision floating-point number Approx. ±1.5e-45 to ±3.4e+38 0.0f
double Double-precision floating-point number Approx. ±5.0e-324 to ±1.7e+308 0.0
decimal 128-bit high-precision decimal type (suitable for financial calculations) ±1.0 x 10-28 to ±7.9 x 1028 0.0m

Boolean Type

Character Type

Note: C# also provides implicit type conversion for some numeric types, but explicit casting is often required to avoid data loss or to convert between incompatible types.

Reference Types

Reference types do not store their data directly; they store a reference (an address) to the location in memory where the data is stored. When you assign a reference type variable to another, both variables point to the same object.

Class Types

User-defined types that can contain data members (fields) and methods.


public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// Usage:
Person person1 = new Person { Name = "Alice", Age = 30 };
Person person2 = person1; // person1 and person2 refer to the same object
            

Interface Types

Define a contract for classes to implement, specifying methods, properties, and events that a class must provide.

Array Types

Represent a fixed-size sequence of elements of the same type.


int[] numbers = new int[5]; // An array of 5 integers, initialized to 0
string[] names = { "Bob", "Charlie", "David" }; // An array initialized with values
            

Delegate Types

Represent references to methods with a particular signature. Used for event handling and callback mechanisms.

Enumeration Types (Enums)

Define a set of named constants.


public enum DayOfWeek
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
}

// Usage:
DayOfWeek today = DayOfWeek.Wednesday;
            

String Type

Represents a sequence of characters. Strings in C# are immutable reference types.


string greeting = "Hello, World!";
string message = greeting + " Welcome!"; // Creates a new string
            

Object Type

The ultimate base type of all types in C#. An object can hold values of any other type (value or reference).


object obj = 10; // obj holds an integer
obj = "Hello";  // obj now holds a string
            
Tip: Understanding the difference between value types (copy by value) and reference types (copy by reference) is crucial for avoiding common bugs related to unintended data modification.

Nullable Types

For value types, which cannot normally hold a null value, C# introduces nullable types using the ? suffix. This allows a value type to be assigned null.


int? nullableInt = null;
int? anotherNullableInt = 5;

if (nullableInt.HasValue)
{
    Console.WriteLine(nullableInt.Value);
}
else
{
    Console.WriteLine("nullableInt is null.");
}
            

Type Conversion

C# supports several ways to convert between types: