1. Wprowadzenie
Próbowałeś kiedyś wcisnąć arbuza do butelki? No właśnie, C# ma podobny problem za każdym razem, gdy prosisz go o przypisanie zmiennej jednego typu do drugiego. Czasem to proste (małą liczbę zamienić na dużą — jak wrzucić jabłko do walizki), a czasem trzeba uważać (arbuz do butelki — tu bez problemów się nie obejdzie).
Konwersja typu — to operacja przekształcenia wartości z jednego typu danych na inny. Często jest to potrzebne, gdy chcesz dodać lub porównać wartości różnych typów, albo przekazać je do metod, które przyjmują tylko określony typ.
W prawdziwym życiu programiści spotykają się z tym non stop: robisz płatność, liczysz zniżki, wykonujesz obliczenia fizyczne albo, na przykład, parsujesz liczby wpisane przez użytkownika z klawiatury (tam wszystko przychodzi jako string).
2. Niejawna konwersja typów (Implicit Conversion)
Co to jest?
Niejawna konwersja — to wtedy, gdy C# sam za Ciebie decyduje, że można bezpiecznie „przełożyć” dane z jednego typu do drugiego. Wszystko dzieje się automatycznie — nic nie piszesz, po prostu używasz wartości.
- Kompilator się nie czepia.
- Nie trzeba żadnych specjalnych komend ani castów.
- Nie ma utraty danych (no, prawie nigdy).
Przykład niejawnej konwersji
int a = 42;
double b = a; // Niejawna konwersja int -> double
Console.WriteLine(b); // 42 (ale to już 42.0)
Tutaj a z typu int automatycznie staje się double przy przypisaniu do zmiennej b. Nie ma utraty danych, bo wszystkie wartości int spokojnie mieszczą się w double.
Tutaj a z typu int automatycznie staje się double przy przypisaniu do zmiennej b. Nie ma utraty danych, bo wszystkie wartości int spokojnie mieszczą się w double.
Kiedy to działa?
- Kiedy typ docelowy jest szerszy niż źródłowy — obsługuje szerszy zakres danych.
- Nie ma utraty danych.
- Przykłady:
- int → long
- int → float / double
- float → double
- char → int
Kolejny przykład:
byte x = 100;
int y = x; // byte -> int (wszystkie wartości byte mieszczą się w zakresie int)
Tabela niejawnych konwersji dla typów liczbowych
| From | To |
|---|---|
|
|
|
|
|
|
|
|
3. Jawna konwersja typów (Explicit Conversion, Type Cast)
Kiedy brakuje magii?
Czasem kompilator nie może zagwarantować, że konwersja będzie bezpieczna, i wymaga od Ciebie wzięcia odpowiedzialności — musisz jawnie powiedzieć, że rozumiesz ryzyko.
- Możliwa utrata danych.
- Format wartości może się zmienić.
- Czasem konwersja jest w ogóle niemożliwa — dostaniesz błąd.
Jak zapisać jawną konwersję?
Używamy składni z nawiasami (cast):
double pi = 3.1415;
int wholePi = (int)pi; // Jawna konwersja double -> int
Console.WriteLine(wholePi); // 3 (część po przecinku znika!)
Kiedy stosować?
- Kiedy typ docelowy jest węższy niż źródłowy — zakres wartości docelowego jest mniejszy niż źródłowego.
- Możliwa utrata części po przecinku, danych, przepełnienie.
- Przykłady:
- double → int
- long → int
- int → byte
- Prawie każde przejście między niekompatybilnymi typami.
4. Rozkminiamy na przykładach
1) Tracimy dane? Sprawdźmy!
Niejawna konwersja — wszystko git!
int small = 25;
long big = small; // Niejawna konwersja (int -> long)
Console.WriteLine(big); // 25
Jawna konwersja — strefa ryzyka!
int big = 1000;
byte small = (byte)big; // Jawna konwersja (int -> byte)
Console.WriteLine(small); // 232 (!), bo 1000 nie mieści się w byte (0..255)
Tutaj wynik to „magiczne” 232, bo 1000 % 256 == 232.
2) Z liczbami zmiennoprzecinkowymi (double, float)
double number = 9.99;
int approximate = (int)number; // część po przecinku po prostu znika
Console.WriteLine(approximate); // 9
3) Konwersja między całkowitymi i zmiennoprzecinkowymi (double ↔ int)
int apples = 5;
double exactApples = apples; // int -> double (niejawnie)
Console.WriteLine(exactApples); // 5.0
double bananaWeight = 2.77;
int weightForReport = (int)bananaWeight; // double -> int (jawnie)
Console.WriteLine(weightForReport); // 2
5. Co zrobić z konwersją stringów: Parse i Convert
Konwersja typów nie działa między liczbami a stringami! Tu potrzebne są specjalne metody, na przykład:
string strNumber = "123";
int num = int.Parse(strNumber); // albo Convert.ToInt32(strNumber);
Ale odwrotnie (int → string) dzieje się automatycznie przy konkatenacji stringów:
int number = 42;
string message = "Odpowiedź: " + number; // Niejawna konwersja int → string
6. Błędy przy konwersji typów
Historia z życia: ktoś kiedyś zapomniał jawnie przekonwertować typ i końcowa płatność była 250 razy mniejsza niż powinna... Studenci, bądźcie czujni!
Częsty błąd: próba niejawnej konwersji typu, gdzie możliwa jest utrata danych.
int big = 500;
byte small = big; // Kompilator: "Nie można! Możliwa utrata danych!"
Tutaj potrzebna będzie jawna konwersja:
byte small = (byte)big; // Ale ryzykujesz utratę danych!
Inny popularny bug — zapomniano o części po przecinku:
double x = 2.9;
int y = (int)x; // y == 2, część po przecinku znika
Żeby zaokrąglić zgodnie z matematyką, użyj Math.Round:
int y = (int)Math.Round(x); // y == 3
7. Pułapki konwersji
- Utrata danych. Zawsze sprawdzaj, czy wartość nie wychodzi poza dozwolony zakres typu. Na przykład, int mieści od -2 147 483 648 do 2 147 483 647, a byte — tylko 0–255.
- Zaokrąglanie. Zwykła konwersja ((int)x) po prostu ucina część po przecinku. Do poprawnego zaokrąglania używaj Math.Round, Math.Floor, Math.Ceiling.
- Literały liczbowe. Zwróć uwagę, że zapis 3 / 2 da 1 (dzielenie całkowite), a 3.0 / 2 — już 1.5 (double)!
- Operacje mieszanych typów. Jeśli w wyrażeniu mieszają się np. int i double, wynik będzie typu double.
GO TO FULL VERSION