CodeGym /Kursy /C# SELF /Jawna i niejawna konwersja typów

Jawna i niejawna konwersja typów

C# SELF
Poziom 6 , Lekcja 5
Dostępny

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:
    • intlong
    • intfloat / double
    • floatdouble
    • charint

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
byte
short, ushort, int, uint, long, ulong, float, double, decimal
int
long, float, double, decimal
float
double
char
ushort, int, uint, long, ulong, float, double, decimal

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:
    • doubleint
    • longint
    • intbyte
    • 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)

Uwaga::

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 (intstring) 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.
1
Ankieta/quiz
Liczby rzeczywiste, poziom 6, lekcja 5
Niedostępny
Liczby rzeczywiste
Problemy z precyzją i wartości specjalne
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION