1. Introduction
Ever tried to shove a watermelon into a bottle? Well, C# faces a similar challenge every time you ask it to assign a variable of one type to another. Sometimes it's easy (turning a small number into a big one — like putting an apple in a suitcase), and sometimes you gotta be careful (watermelon in a bottle — that's not gonna go smoothly).
Type casting is the operation of converting a value from one data type to another. You often need this when you want to add or compare values of different types, or pass them to methods that only accept a certain type.
In real life, programmers run into this all the time: you're making a payment, calculating discounts, doing physics calculations, or, for example, parsing numbers entered by a user from the keyboard (everything comes in as a string there).
2. Implicit Conversion
What's that?
Implicit conversion is when C# decides for you that it's safe to "move" data from one type to another. It all happens automatically — you don't write anything special, you just use the values.
- The compiler doesn't complain.
- No special commands or casts needed.
- No data loss (well, almost never).
Example of implicit conversion
int a = 42;
double b = a; // Implicit conversion int -> double
Console.WriteLine(b); // 42 (but now it's 42.0)
Here, a of type int automatically becomes double when assigned to variable b. No data loss, since all int values easily fit into a double.
Here, a of type int automatically becomes double when assigned to variable b. No data loss, since all int values easily fit into a double.
When does this work?
- When the receiving type is wider than the source type — supports a wider range of data.
- No data loss happens.
- Examples:
- int → long
- int → float / double
- float → double
- char → int
Another example:
byte x = 100;
int y = x; // byte -> int (all byte values fit in int range)
Table of implicit conversions for numeric types
| From | To |
|---|---|
|
|
|
|
|
|
|
|
3. Explicit Conversion (Type Cast)
When the magic isn't enough?
Sometimes the compiler can't guarantee the conversion is safe, and it wants you to take responsibility — explicitly tell it you know the risks.
- You might lose data.
- The value's format might change.
- Sometimes the conversion just isn't possible — you'll get an error.
How do you write an explicit cast?
Use the parentheses syntax (cast):
double pi = 3.1415;
int wholePi = (int)pi; // Explicit conversion double -> int
Console.WriteLine(wholePi); // 3 (fractional part is dropped!)
When do you use it?
- When the receiving type is narrower than the source type — the receiver's value range is smaller than the source's.
- You might lose the fractional part, data, or get overflow.
- Examples:
- double → int
- long → int
- int → byte
- Pretty much any conversion between incompatible types.
4. Let's Check Out Some Examples
1) Are We Losing Data? Let's Check!
Implicit conversion — all good!
int small = 25;
long big = small; // Implicit conversion (int -> long)
Console.WriteLine(big); // 25
Explicit conversion — danger zone!
int big = 1000;
byte small = (byte)big; // Explicit conversion (int -> byte)
Console.WriteLine(small); // 232 (!), because 1000 doesn't fit in byte (0..255)
Here the result is the "magic" 232, because 1000 % 256 == 232.
2) With floating point numbers (double, float)
double number = 9.99;
int approximate = (int)number; // fractional part just gets dropped
Console.WriteLine(approximate); // 9
3) Conversion between integers and floating point (double ↔ int)
int apples = 5;
double exactApples = apples; // int -> double (implicit)
Console.WriteLine(exactApples); // 5.0
double bananaWeight = 2.77;
int weightForReport = (int)bananaWeight; // double -> int (explicit)
Console.WriteLine(weightForReport); // 2
5. What About String Conversion: Parse and Convert
Type casting doesn't work between numbers and strings! Here you need special methods, for example:
string strNumber = "123";
int num = int.Parse(strNumber); // or Convert.ToInt32(strNumber);
But the reverse (int → string) happens automatically when you concatenate strings:
int number = 42;
string message = "Answer: " + number; // Implicit conversion int → string
6. Type Casting Errors
History lesson: once someone forgot to cast a type explicitly, and the final payment turned out to be 250 times less than needed... Students, pay attention!
A common mistake: trying to implicitly convert a type where data loss is possible.
int big = 500;
byte small = big; // Compiler: "No way! Possible data loss!"
Here you need an explicit cast:
byte small = (byte)big; // But you risk losing data!
Another popular bug — forgot about the fractional part:
double x = 2.9;
int y = (int)x; // y == 2, fractional part is gone
To round according to math rules, use Math.Round:
int y = (int)Math.Round(x); // y == 3
7. Conversion Gotchas
- Data loss. Always check if the value goes out of the allowed range for the type. For example, int holds from -2 147 483 648 to 2 147 483 647, and byte — only 0–255.
- Rounding. Regular casting ((int)x) just drops the fractional part. For proper rounding use Math.Round, Math.Floor, Math.Ceiling.
- Numeric literals. Watch out: writing 3 / 2 gives you 1 (integer division), but 3.0 / 2 gives you 1.5 (double)!
- Mixed type operations. If you mix, say, int and double in an expression, the result will be of type double.
GO TO FULL VERSION