Data types in C# define what kind of value a variable can store. A data type tells the compiler whether a value is a whole number, decimal number, character, text, Boolean value, object reference, date, or another kind of data. Because C# is a strongly typed language, every variable, parameter, field, property, and return value has a type.
Understanding data types is one of the most important steps in learning C#. If you choose the wrong type, your program may waste memory, lose precision, reject valid values, or become harder to read. If you choose the right type, your code becomes clearer, safer, and easier for the compiler to check.
What Are Data Types in C#?
A data type is a classification of data. It decides the kind of value that can be stored and the operations that can be performed on that value.
int age = 25;
string name = "Alex";
bool isActive = true;
Here, age is an integer, name is text, and isActive is a Boolean value. The compiler uses these types to validate assignments and operations.
A C# data type answers two questions: what kind of value is stored, and what operations are valid on that value?
Main Categories of Data Types in C#
| Category | Examples | Basic Meaning |
|---|---|---|
| Value types | int, double, bool, char, struct | Store the actual value directly. |
| Reference types | string, arrays, classes, interfaces | Store a reference to an object. |
| Pointer types | Pointers in unsafe code | Used only in special unsafe contexts. |
Most beginner C# programming focuses on value types and reference types. Pointer types are advanced and not used in normal C# application development.
Integer Data Types in C#
Integer types store whole numbers without decimal points. C# provides signed and unsigned integer types with different sizes.
| Type | Size | Range Idea |
|---|---|---|
byte | 1 byte | 0 to 255 |
sbyte | 1 byte | Small signed integers |
short | 2 bytes | Signed small integers |
ushort | 2 bytes | Unsigned small integers |
int | 4 bytes | Most common whole-number type |
uint | 4 bytes | Unsigned integer |
long | 8 bytes | Large signed integers |
ulong | 8 bytes | Large unsigned integers |
In most regular programs, int is the default choice for whole numbers. Use long when the value can become larger than the range of int.
Floating-Point and Decimal Types
C# provides three common types for numbers with decimal parts: float, double, and decimal.
| Type | Size | Best Use |
|---|---|---|
float | 4 bytes | Approximate decimal values with less precision |
double | 8 bytes | General scientific or mathematical decimal calculations |
decimal | 16 bytes | Financial and money-like calculations |
float temperature = 36.6f;
double distance = 1520.75;
decimal price = 199.99m;
Notice the suffixes. A float literal commonly uses f, while a decimal literal uses m. Without a suffix, many decimal literals are treated as double.
char Data Type
The char type stores a single Unicode character. Character values are written inside single quotes.
char grade = 'A';
char symbol = '#';
Use char for one character. Use string for multiple characters or text.
bool Data Type
The bool type stores only two values: true or false. It is used in conditions, flags, validation checks, loops, and logical decisions.
bool isLoggedIn = true;
bool hasPermission = false;
Unlike some languages, C# does not treat numbers like 0 and 1 as Boolean values in conditions. A condition must be an actual Boolean expression.
string Data Type
The string type stores text. String values are written inside double quotes.
string name = "Nerds Do Stuff";
string message = "Learning C# data types";
Technically, string is a reference type, but it behaves in a very convenient and beginner-friendly way. Strings are immutable, which means once a string object is created, its content is not changed directly. Operations that appear to modify a string usually create a new string.
object Data Type
The object type is the base type of all types in C#. A variable of type object can hold values of many different types, but using it too casually can reduce type safety and readability.
object value = 100;
value = "Hello";
This is valid, but normal code should prefer specific types unless there is a clear reason to use object.
Value Types vs Reference Types
A value type variable stores the actual value. A reference type variable stores a reference to an object. This affects copying, assignment, memory behavior, and method calls.
int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // 10
Console.WriteLine(b); // 20
For value types, assigning one variable to another usually copies the value. Reference types can behave differently because the reference may point to the same object.
Nullable Types in C#
Normally, value types such as int and bool cannot store null. If you want a value type to also represent no value, you can use a nullable type.
int? age = null;
bool? isApproved = null;
The ? means the variable can store either a normal value or null. This is useful for optional data, database fields, forms, and values that may be unknown.
Default Values of C# Data Types
| Type | Default Value |
|---|---|
int | 0 |
double | 0.0 |
bool | false |
char | '\0' |
decimal | 0.0m |
| Reference types | null |
Fields receive default values automatically, but local variables must be assigned before they are read. This rule prevents many accidental bugs in local code.
Implicit and Explicit Type Conversion
C# allows safe automatic conversion in some cases. For example, an int can be assigned to a long because a long has a wider range.
int smallNumber = 100;
long bigNumber = smallNumber;
But when conversion may lose data, you need an explicit cast.
double price = 99.95;
int rounded = (int)price;
This conversion drops the decimal part, so it should be used carefully.
enum Data Type in C#
An enum is a user-defined value type used to represent a fixed set of named constants. It is useful when a value should be selected from a known group, such as days, status values, directions, or order states.
enum OrderStatus
{
Pending,
Processing,
Shipped,
Delivered
}
OrderStatus status = OrderStatus.Pending;
Using an enum is clearer than using random numbers or strings because the possible values are named and controlled by the type.
DateTime and Guid Types
C# also provides useful framework types such as DateTime and Guid. DateTime stores date and time values, while Guid stores globally unique identifiers commonly used for IDs in databases, APIs, and distributed systems.
DateTime createdAt = DateTime.Now;
Guid userId = Guid.NewGuid();
These are not primitive language keywords like int or bool, but they are extremely common in real C# applications.
Nullable Reference Types
Modern C# supports nullable reference type analysis. When enabled, the compiler can warn you when a reference variable may contain null and you are using it unsafely. This feature is designed to reduce null reference errors, which are among the most common bugs in application code.
string name = "Alex";
string? optionalName = null;
The ? after string communicates that optionalName is allowed to be null. This makes intent clearer and helps the compiler provide better warnings.
Literals and Type Suffixes
A literal is a fixed value written directly in code. Examples include 10, 99.5, 'A', "Hello", true, and false. Some literals need suffixes so the compiler understands the intended type clearly.
long population = 1400000000L;
float ratio = 0.75f;
decimal amount = 1200.50m;
These suffixes avoid ambiguity. They are especially common with long, float, and decimal values.
Choosing the Right Data Type
- Use
intfor normal whole numbers. - Use
longfor very large whole numbers. - Use
doublefor general decimal calculations. - Use
decimalfor money and financial values. - Use
boolfor true or false conditions. - Use
charfor a single character. - Use
stringfor text. - Use nullable types when a value may be missing.
Another useful habit is to think about whether a type is part of the language syntax or part of the .NET library. Keywords like int, bool, and string are aliases for framework types such as System.Int32, System.Boolean, and System.String. This connection helps when reading documentation and error messages.
Common Mistakes with Data Types in C#
- Using
doublefor money instead ofdecimal. - Confusing
charandstring. - Expecting
0or1to work as Boolean values. - Assigning a larger numeric type to a smaller numeric type without casting.
- Using
objectwhen a specific type would be clearer. - Forgetting that strings are reference types and immutable.
What is the most commonly used numeric type in C#?
int is the most common whole-number type, while double is commonly used for general decimal calculations.
Should I use double or decimal for money in C#?
Use decimal for money because it is designed for higher precision decimal calculations and avoids many floating-point representation issues.
Is string a value type or reference type in C#?
string is a reference type, but it is immutable and has special language support, so it often feels simpler than many other reference types.
Best Practices for C# Data Types
- Choose the type that matches the real meaning of the data.
- Prefer specific types over
object. - Use
decimalfor currency and financial calculations. - Use nullable types only when missing data is a real possibility.
- Do not use larger types only because they feel safer; choose based on actual range and precision needs.
- Keep type conversions explicit when data loss may happen.
Data types in C# are the foundation of type safety. They help the compiler protect your program from invalid operations, make values easier to understand, and guide how memory and runtime behavior work behind the scenes.