Understanding data types is one of the most important foundations in C#.
Whenever you create a variable, C# needs to know what kind of data that variable will store.
For example:
int age = 25;
string name = "Shreya";
bool isActive = true;
decimal salary = 50000.50m;Here:
intstores a whole numberstringstores textboolstorestrueorfalsedecimalstores a high-precision decimal number
But C# data types are not just about what kind of value they store.
They are also important because different types behave differently in memory.
At a high level, C# types are commonly divided into:
C# Data Types
Value Types
├── Integer
│ ├── byte
│ ├── short
│ ├── int
│ └── long
│
├── Decimal numbers
│ ├── float
│ ├── double
│ └── decimal
│
├── bool
├── char
├── enum
└── struct
Reference Types
├── string
├── object
├── arrays
├── class
├── interface
└── delegateIn this article, we will understand each of these in depth.
---
1. What is a Data Type in C#?
A data type tells C#:
- what kind of value a variable can store
- how much memory may be required
- what operations are allowed
- how the value behaves when assigned or passed around
- what range or precision the value supports
Consider:
int age = 25;C# knows that age contains an integer.
Because it is an int, we can perform arithmetic:
age = age + 1;But this would not be valid:
age = "Twenty Five";because "Twenty Five" is a string, not an int.
This type checking is one reason C# is called a statically typed language.
The compiler knows the type of most variables before the program runs.
---
2. Value Types vs Reference Types
This is the most important distinction to understand.
Value types
A value-type variable contains its value directly.
For example:
int a = 10;
int b = a;At this point:
a = 10
b = 10Now change b:
b = 20;Result:
a = 10
b = 20Changing b does not change a.
Why?
Because the value was copied.
Conceptually:
a ---> 10
b ---> 10Each variable has its own value.
Common value types include:
int
long
float
double
decimal
bool
char
enum
struct---
Reference types
A reference-type variable generally holds a reference to an object rather than containing that entire object value directly.
For example:
int[] first = { 10, 20, 30 };
int[] second = first;Now both variables refer to the same array.
Conceptually:
first ----\
---> [10, 20, 30]
second ----/If we write:
second[0] = 100;then:
Console.WriteLine(first[0]);prints:
100because both variables refer to the same array.
This difference between copying a value and copying a reference is fundamental in C#.
---
3. Integer Types
Integer types store whole numbers.
Examples:
0
10
-15
5000
1000000They do not store fractional values such as:
10.5
3.14C# provides several integer types.
---
byte
A byte is an 8-bit unsigned integer.
Range:
0 to 255Example:
byte marks = 95;This is valid:
byte value = 200;This is not:
byte value = 300;because 300 exceeds the maximum byte value.
When might byte be useful?
It is commonly useful when working with:
- raw binary data
- files
- network packets
- images
- streams
For example:
byte[] imageData;---
sbyte
There is also a signed version of byte:
sbyte temperature = -20;Range:
-128 to 127The s means signed.
Signed types can represent negative values.
Unsigned types cannot.
---
4. short
A short is a 16-bit signed integer.
Example:
short year = 2026;Range:
-32,768 to 32,767There is also:
ushortwhich is unsigned.
Its range is:
0 to 65,535In normal application development, short is used less frequently than int.
---
5. int
int is the most commonly used whole-number type in C#.
Example:
int age = 25;
int employeeCount = 500;
int marks = 95;int is a 32-bit signed integer.
Its approximate range is:
-2.1 billion to +2.1 billionMore exactly:
-2,147,483,648
to
2,147,483,647For most everyday whole numbers, int should be your default choice.
---
uint
uint means:
unsigned integerExample:
uint population = 100000;It does not allow negative values.
Its range is roughly:
0 to 4.29 billionEven though uint provides a larger positive range than int, int is usually more convenient because many .NET APIs use signed integers.
---
6. long
When int is not large enough, use long.
Example:
long worldPopulation = 8_000_000_000L;The suffix L tells C# that the literal should be treated as a long.
long is a 64-bit signed integer.
Its range is extremely large:
approximately
-9.22 quintillion
to
+9.22 quintillionExamples where long can be appropriate include:
- large database identifiers
- timestamps
- file sizes
- very large counters
- large numeric calculations
There is also an unsigned version:
ulong---
7. Floating-Point and Decimal Types
C# provides three important types for numbers containing fractional parts:
float
double
decimalThey are not interchangeable in every situation.
---
8. float
A float is a 32-bit floating-point number.
Example:
float temperature = 36.5f;Notice the f.
Without it:
float temperature = 36.5;C# treats 36.5 as a double by default, so this causes a conversion issue.
Correct:
float temperature = 36.5f;Approximate precision:
6–9 significant decimal digitsExample:
float value = 1.23456789f;A float may not preserve every digit exactly.
Common uses
float can be useful for:
- graphics
- game coordinates
- physics calculations where extreme precision is unnecessary
- large collections where memory size matters
---
9. double
double is a 64-bit floating-point type.
Example:
double pi = 3.141592653589793;Approximate precision:
15–17 significant digitsIt is much more precise than float.
Also, decimal-looking numeric literals are double by default:
var number = 10.5;Here, number becomes a double.
Common uses
double is appropriate for many:
- scientific calculations
- mathematical calculations
- measurements
- statistics
- geometry
---
10. decimal
decimal is designed for high-precision decimal arithmetic.
Example:
decimal salary = 50000.75m;Notice the m suffix.
decimal price = 99.99m;Approximate precision:
28–29 significant digitsdecimal is commonly used for:
- money
- salaries
- prices
- taxes
- accounting
- financial calculations
Why not always use double?
Because binary floating-point values such as double may not represent some simple decimal fractions exactly.
For example:
double a = 0.1;
double b = 0.2;
Console.WriteLine(a + b);The internal result may contain a tiny representation error.
For finance, this can be undesirable.
Using:
decimal a = 0.1m;
decimal b = 0.2m;is usually more appropriate.
---
11. float vs double vs decimal
A useful comparison:
| Type | Size | Approx. precision | Typical use |
|---|---|---|---|
float | 4 bytes | 6–9 digits | Graphics, games |
double | 8 bytes | 15–17 digits | General scientific calculations |
decimal | 16 bytes | 28–29 digits | Finance and money |
A simple rule:
Graphics / lower precision → float
General calculation → double
Money → decimal---
12. bool
bool represents Boolean logic.
It has two values:
true
falseExample:
bool isActive = true;
bool isDeleted = false;It is commonly used in conditions:
if (isActive)
{
Console.WriteLine("Employee is active");
}Boolean variables are extremely common in business applications.
Examples:
bool isAdmin;
bool isApproved;
bool hasPermission;
bool isLoggedIn;Good Boolean variable names often start with:
is
has
can
shouldFor example:
bool hasAccess = true;
bool canEdit = false;---
13. char
A char stores one UTF-16 code unit.
Simple examples:
char grade = 'A';
char symbol = '#';
char digit = '5';A char uses single quotes:
'A'A string uses double quotes:
"A"These are different:
char letter = 'A';
string text = "A";Even though both visually contain A, their types are different.
---
14. enum
An enum represents a fixed set of named constants.
Imagine an employee can have one of these statuses:
Active
Inactive
SuspendedInstead of storing arbitrary strings:
string status = "Active";we can create:
enum EmployeeStatus
{
Active,
Inactive,
Suspended
}Then:
EmployeeStatus status = EmployeeStatus.Active;This is safer because the compiler restricts us to valid values.
For example:
if (status == EmployeeStatus.Active)
{
Console.WriteLine("Employee can work");
}Enums improve:
- readability
- type safety
- maintainability
---
15. struct
A struct is a custom value type.
For example:
struct Point
{
public int X;
public int Y;
}Then:
Point p1 = new Point();
p1.X = 10;
p1.Y = 20;Because a struct is a value type, assignment copies its data.
Point p2 = p1;
p2.X = 100;Now:
p1.X = 10
p2.X = 100because p2 received a copy.
Structs are commonly suitable for small values that conceptually represent a single piece of data.
Examples in .NET include types such as:
DateTime
TimeSpan
Guid
decimalThese are structs.
---
16. Reference Types
Now let's move to reference types.
Common reference types include:
string
object
array
class
interface
delegate---
17. string
A string represents text.
Example:
string name = "Shreya";
string city = "Delhi";Strings are reference types.
But strings behave differently from many other reference types because they are immutable.
Immutable means:
Once a string object is created, its contents cannot be changed.
Consider:
string name = "Shreya";
name = name + " Kumari";It may look like the original string was modified.
Conceptually, however, a new string is created and the variable refers to the new string.
This is important when performing many string modifications.
For heavy string building, C# provides:
StringBuilder---
18. object
object is the ultimate base type of C#'s unified type system.
You can write:
object a = 10;
object b = "Hello";
object c = true;Because every C# type can be represented as object.
However, storing value types inside object can involve boxing.
Example:
int number = 10;
object obj = number;The integer value is boxed.
Getting it back:
int result = (int)obj;is called unboxing.
Modern C# code generally prefers generics and strongly typed variables instead of relying heavily on object.
---
19. Arrays
An array stores multiple values of the same type.
Example:
int[] numbers = { 10, 20, 30 };String array:
string[] names =
{
"A