C# Data Types
Data types define the kind of value a variable can hold and the operations that can be performed on it. C# is a strongly-typed language, meaning that every variable must have a declared type. This helps to prevent type errors at runtime and improves code reliability and performance.
C# data types are broadly categorized into two main groups:
Value Types
Value types directly contain their data. When you assign a value type variable to another, the value is copied. Examples include primitive types like integers, floating-point numbers, and booleans, as well as enumeration types and structures (structs).
Built-in Value Types
The following table lists the common built-in value types in C#:
Type | Description | Range/Precision | 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.5 x 10-45 to ±3.4 x 1038 (7 digits of precision) | 0.0f |
double |
Double-precision floating-point number | Approx. ±5.0 x 10-324 to ±1.7 x 10308 (15-17 digits of precision) | 0.0d |
decimal |
128-bit decimal type for financial calculations | Approx. ±1.0 x 10-28 to ±7.9 x 1028 (28-29 digits of precision) | 0.0m |
bool |
Boolean value (true or false) | true or false | false |
char |
16-bit Unicode character | U+0000 to U+FFFF | '\0' |
struct |
User-defined type that can encapsulate related data and behavior. | Varies | Default values for fields |
enum |
User-defined type consisting of a set of named constants. | Varies | The first enumerator value |
Reference Types
Reference types do not contain their data directly. Instead, they store a reference (or pointer) to the location in memory where the data is stored. When you assign a reference type variable to another, the reference is copied, meaning both variables point to the same object in memory. Examples include classes, interfaces, delegates, arrays, and strings.
Common Reference Types
string
: Represents a sequence of Unicode characters. Strings are immutable in C#, meaning their content cannot be changed after creation.object
: The ultimate base type of all types in C#. Any type can be converted to an object and vice versa (with casting).class
: User-defined types that can contain fields, methods, properties, and events. They support inheritance and polymorphism.interface
: A contract that defines a set of members that a class must implement. Interfaces do not contain implementation details.delegate
: Represents a reference type that can be used to encapsulate a method with a specific signature. Delegates are essential for event handling.array
: A data structure that holds a fixed-size collection of elements of the same type.
When a reference type variable is not assigned a value, its default value is null
.
Type Casting and Conversion
C# supports implicit and explicit type conversions. An implicit conversion occurs when no data is lost. An explicit conversion (casting) is required when data might be lost or when converting between incompatible types. This must be done carefully to avoid runtime errors.
int myInt = 100;
long myLong = myInt; // Implicit conversion from int to long
double myDouble = 9.78;
int myInt = (int) myDouble; // Explicit conversion (casting) from double to int
// myInt will be 9, data loss occurs
Nullable Types
By default, value types cannot be null. However, you can declare nullable value types by appending a ?
to the type name (e.g., int?
, bool?
). Nullable types allow you to assign null
to value types.
int? nullableInt = null;
if (nullableInt.HasValue)
{
Console.WriteLine($"Value: {nullableInt.Value}");
}
else
{
Console.WriteLine("The nullable integer is null.");
}
Understanding C# data types is fundamental to writing effective and robust code. By choosing the appropriate data type for your variables, you can ensure type safety, optimize memory usage, and improve the overall performance of your applications.