1. Вирази vs інструкції
У C# усі конструкції поділяють на дві категорії: інструкції (Statement) і вирази (Expression). Про інструкцію зазвичай кажуть, що її виконують, а про вираз — що його обчислюють. Та це не головне.
Головна відмінність: вираз має результат обчислення. Цей результат має тип, і його можна присвоїти змінній або використати в іншому виразі.
Приклади:
| Код | Примітки |
|---|---|
|
Інструкція |
|
Вираз, тип bool |
|
Вираз, тип збігається з типом змінної i |
|
Вираз, тип збігається з типом змінної x |
Що це нам дає?
Чимало інструкцій насправді є виразами (мають результат обчислення). Наприклад, такий код працює:int x, y, z;
x = y = z = 1; // x = (y = (z = 1));
Можна проігнорувати результат виразу, якщо він не потрібен:
Console.ReadLine(); // ігноруємо результат введення
Це зручно, коли вираз, окрім результату, робить щось корисне (наприклад, виводить на екран або читає введення).
2. Тернарний оператор
У C# є спеціальний тернарний (потрійний) оператор. Він схожий на скорочений запис оператора if–else:
Умова ? Вираз1 : Вираз2;
Якщо Умова істинна, обчислюється Вираз1, інакше — Вираз2. Після умови ставиться ?, а два вирази розділяються :.
Головна відмінність від if-else: тернарний оператор — це вираз, його результат можна присвоїти змінній або використати в інших виразах.
Наприклад, обчислимо мінімум двох чисел:
int a = 2;
int b = 3;
int min = a < b ? a : b;
Або присвоїмо змінній різні значення залежно від умови:
int age = 25;
int money;
if (age > 30)
money = 100;
else
money = 50;
Те саме з тернарним оператором:
int age = 25;
int money = age > 30 ? 100 : 50;
Що краще використовувати: if-else чи тернарний оператор? За швидкістю різниці немає, але тернарний оператор зручний для коротких умов. Якщо код не вміщується в один рядок — краще використовувати if-else для зручності читання.
3. Нюанси використання
Типи значень
Обидві гілки тернарного оператора (<значення_якщо_істина> і <значення_якщо_хиба>) мають бути одного типу або сумісні (наприклад, обидва string або обидва int).
Працює:
int a = 10, b = 20;
int max = (a > b) ? a : b; // обидві гілки — int
Помилка компіляції:
int a = 10, b = 20;
// string і int не сумісні
string result = (a > b) ? "більше" : 0; // Помилка компіляції
Правильний варіант:
int a = 10, b = 20;
string result = (a > b) ? "більше" : "менше або дорівнює";
Приклад: робота з числами
int number = -5;
int abs = (number >= 0) ? number : -number;
Console.WriteLine(abs); // 5
4. Вбудовування тернарного оператора в застосунок
Напишімо невеликий діалоговий застосунок: окрім привітання, програма повідомить, скільки років вам буде за рік, і підкаже, чи будете ви повнолітніми.
Console.Write("Введіть ваше імʼя: ");
string name = Console.ReadLine();
Console.Write("Введіть ваш вік: ");
string ageText = Console.ReadLine();
int age = int.Parse(ageText);
int nextYear = age + 1;
string status = (nextYear >= 18) ? "повнолітній" : "неповнолітній";
Console.WriteLine($"Привіт, {name}! Наступного року вам буде {nextYear}. Ви будете {status}.");
Пояснимо деталі:
- Змінна status обчислюється через тернарний оператор: якщо вік за рік становитиме щонайменше 18, користувач буде повнолітнім (або залишиться ним).
- Тернарний оператор можна легко інтегрувати безпосередньо в рядки (наприклад, в інтерполяцію $"").
5. Вкладені тернарні оператори — обережно!
Тернарний оператор можна вкладати один в інший (у кожній із гілок може бути ще один тернарний оператор). Але… від цього зазвичай болить голова, особливо у того, хто читатиме код після вас (навіть якщо це ви за два дні).
Приклад: визначення категорії за віком
string category = (age < 7) ? "дошкільник" :
(age < 18) ? "школяр" :
(age < 65) ? "дорослий" : "пенсіонер";
Таблиця прийняття рішення:
| Вік | Умова | Результат |
|---|---|---|
| < 7 | age < 7 | дошкільник |
| 7–17 | age < 18 | школяр |
| 18–64 | age < 65 | дорослий |
| 65 і більше | інакше | пенсіонер |
Такий код ще можна читати, але якщо логіка складніша — краще використовувати if-else if-else.
6. Порада: тернарний оператор і тип bool
Іноді трапляється такий код:
bool adult = (age >= 18) ? true : false;
Але це зайве. Сам вираз (age >= 18) уже повертає bool. Тому можна просто:
bool adult = (age >= 18);
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ