JavaRush /Курси /C# SELF /Явне та неявне перетворення типів

Явне та неявне перетворення типів

C# SELF
Рівень 6 , Лекція 5
Відкрита

1. Вступ

Чи доводилося вам намагатися запхнути кавун у пляшку? От і C# стикається з подібним завданням щоразу, коли ви просите його присвоїти значення змінної одного типу змінній іншого типу. Іноді це просто (менше число у більший тип — як покласти яблуко у валізу), а іноді слід бути обережними (кавун у пляшку — тут без пригод не обійтися).

Перетворення типу — це операція перетворення значення з одного типу даних на інший. Воно часто потрібне, коли ви хочете додати або порівняти значення різних типів чи передати їх у методи, що приймають лише певний тип.

У реальних задачах із цим стикаються постійно: ви обробляєте платежі, рахуєте знижки, виконуєте фізичні обчислення або, наприклад, працюєте з числами, введеними користувачем із клавіатури (усе надходить рядком).

2. Неявне перетворення типів (Implicit Conversion)

Що це таке?

Неявне перетворення — це коли C# автоматично визначає, що можна безпечно «перекласти» дані з одного типу в інший. Усе відбувається автоматично — вам нічого додатково писати не потрібно.

  • Компілятор не повідомляє про помилки.
  • Не потрібні спеціальні команди чи кастування.
  • Втрати даних немає (майже ніколи).

Приклад неявного перетворення

int a = 42;
double b = a; // Неявне перетворення int -> double

Console.WriteLine(b); // 42 (але це вже 42.0)

Тут a з типу int автоматично стає double під час присвоєння змінній b. Втрати даних немає, адже всі значення int легко вміщаються в double.

Тут a з типу int автоматично стає double під час присвоєння змінній b. Втрати даних немає, адже всі значення int легко вміщаються в double.

Коли це працює?

  • Коли цільовий тип ширший за вихідний — підтримує ширший діапазон значень.
  • Не відбувається втрата даних.
  • Приклади:
    • intlong
    • intfloat / double
    • floatdouble
    • charint

Ще один приклад:

byte x = 100;
int y = x; // byte -> int (усі значення byte входять у діапазон значень int)

Таблиця неявних перетворень для числових типів

З У
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. Явне перетворення типів (Explicit Conversion, Type Cast)

Коли не вистачає магії?

Іноді компілятор не може гарантувати, що перетворення буде безпечним, і вимагає від вас узяти відповідальність — явно повідомити, що ви усвідомлюєте ризики.

  • Можлива втрата даних.
  • Формат значення може змінитися.
  • Іноді перетворення взагалі неможливе — ви отримаєте помилку.

Як записувати явне перетворення?

Використовується синтаксис у дужках (cast):

double pi = 3.1415;
int wholePi = (int)pi; // Явне перетворення double -> int

Console.WriteLine(wholePi); // 3 (дробова частина відкидається!)

Коли застосовується?

  • Коли цільовий тип вужчий за вихідний — його діапазон значень менший.
  • Можлива втрата дробової частини, даних, переповнення.
  • Приклади:
    • doubleint
    • longint
    • intbyte
    • Майже будь-які переходи між несумісними типами.

4. Розбираємося на прикладах

1) Втрачаємо дані? Давайте перевіримо!

Неявне перетворення — усе гаразд!

int small = 25;
long big = small; // Неявне перетворення (int -> long)
Console.WriteLine(big); // 25

Явне перетворення — небезпечна зона!

int big = 1000;
byte small = (byte)big; // Явне перетворення (int -> byte)

Console.WriteLine(small); // 232 (!), адже 1000 не вміщається в byte (0..255)

Примітка:

Тут результат — «магічні» 232, бо 1000 % 256 == 232.

2) З числами з плаваючою комою (double, float)

double number = 9.99;
int approximate = (int)number; // дробову частину просто відкидає

Console.WriteLine(approximate); // 9

3) Перетворення між цілими і дійсними (double ↔ int)

int apples = 5;
double exactApples = apples; // int -> double (неявно)
Console.WriteLine(exactApples); // 5.0

double bananaWeight = 2.77;
int weightForReport = (int)bananaWeight; // double -> int (явно)
Console.WriteLine(weightForReport); // 2

5. Що робити з перетворенням рядків: Parse і Convert

Перетворення типів між числами й рядками не працює! Тут потрібні спеціальні методи, наприклад:

string strNumber = "123";
int num = int.Parse(strNumber); // або Convert.ToInt32(strNumber);

Але зворотне (intstring) відбувається автоматично під час конкатенації рядків:

int number = 42;
string message = "Відповідь: " + number; // Неявне перетворення int → string

6. Помилки під час перетворення типів

Історія з практики: якось хтось забув явно перетворити тип, і підсумковий платіж вийшов у 250 разів меншим, ніж треба… Будьте уважні!

Поширена помилка: спроба неявно перетворити тип, де можлива втрата даних.

int big = 500;
byte small = big; // Компілятор: «Не можна! Можлива втрата даних!»

Тут потрібне явне перетворення:

byte small = (byte)big; // Але ви ризикуєте втратити дані!

Ще одна поширена помилка — не враховано дробову частину:

double x = 2.9;
int y = (int)x; // y == 2, дробова частина зникла

Щоб округлити за правилами математики, використовуйте Math.Round:

int y = (int)Math.Round(x); // y == 3

7. Пастки перетворення

  • Втрата даних. Обовʼязково перевіряйте, чи не виходить значення за допустимий діапазон типу. Наприклад, int вміщає від -2 147 483 648 до 2 147 483 647, а byte — тільки 0–255.
  • Округлення. Звичайне перетворення ((int)x) просто відкидає дробову частину. Для правильного округлення використовуйте Math.Round, Math.Floor, Math.Ceiling.
  • Числові літерали. Зверніть увагу, що запис 3 / 2 дасть 1 (цілочисельне ділення), а 3.0 / 2 — уже 1.5 (double)!
  • Операції змішаних типів. Якщо у виразі змішуються, наприклад, int і double, результат матиме тип double.
1
Опитування
Дійсні числа, рівень 6, лекція 5
Недоступний
Дійсні числа
Проблеми точності та спеціальні значення
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ