Урок 3.5 — Тернарный оператор
Короткая запись if-else в одной строке. Красиво и опасно одновременно.
Бывает, что нужно присвоить переменной одно из двух значений в зависимости от условия. Конечно, можно написать if-else. Но есть способ короче. Тернарный оператор — это как if-else, но сжатый до одной строки и возвращающий значение. Сегодня мы научимся пользоваться этим мощным, но опасным инструментом.
Синтаксис тернарного оператора
Тернарный оператор называется так, потому что он принимает три операнда. В C# он выглядит так:
Общая схема:
условие ? значение_если_true : значение_если_false
Пример: string result = age >= 18 ? "Взрослый" : "Ребёнок";
Как это работает:
- Вычисляется условие (оно должно быть bool)
- Если условие true — возвращается то, что после
? - Если условие false — возвращается то, что после
:
int age = 20;
string status = age >= 18 ? "Взрослый" : "Несовершеннолетний";
Console.WriteLine(status); // Взрослый
// Полная запись с if-else (то же самое):
// string status;
// if (age >= 18)
// status = "Взрослый";
// else
// status = "Несовершеннолетний";
Сравнение с if-else
Тернарный оператор не заменяет if-else полностью. Это инструмент для конкретной ситуации: когда нужно выбрать одно из двух значений (не выполнить действие, а именно вернуть значение).
Тернарный оператор
int max = a > b ? a : b;
Коротко, лаконично. Но только для выбора значения.
if-else
int max;
if (a > b)
max = a;
else
max = b;
Длиннее, но можно выполнить целые блоки кода.
Когда if-else незаменим:
- Нужно выполнить целый блок кода (несколько строк)
- Нужно вызвать методы с побочными эффектами (например, логирование)
- Условий больше двух (if-else if-else)
Применение в присваивании
Самое частое применение тернарного оператора — присвоить переменной одно из двух значений:
int score = 85;
string grade = score >= 60 ? "Сдал" : "Не сдал";
Console.WriteLine(grade); // Сдал
// С числами:
int a = 10;
int b = 25;
int max = a > b ? a : b; // 25
int min = a < b ? a : b; // 10
// С булевыми значениями:
int temperature = 30;
bool isHot = temperature > 25 ? true : false;
// Но можно и проще: bool isHot = temperature > 25;
temperature > 25 ? true : false — это то же самое, что просто temperature > 25.Применение в Console.WriteLine и аргументах
Тернарный оператор можно использовать прямо внутри вызова метода, в аргументах, в интерполяции строк. Это делает код компактнее:
int age = 17;
Console.WriteLine(age >= 18 ? "Добро пожаловать!" : "Доступ запрещён!");
// В интерполяции строк:
string name = "Анна";
bool isPremium = true;
Console.WriteLine($"Клиент {name} — {(isPremium ? "премиум" : "обычный")}");
// В аргументах методов:
int x = 42;
int y = 15;
Console.WriteLine($"Большее число: {Max(x, y)}");
// Свой вспомогательный метод, использующий тернарный:
static int Max(int a, int b) => a > b ? a : b;
⚠️ Обрати внимание на скобки вокруг тернарного оператора внутри интерполяции: {(isPremium ? "премиум" : "обычный")}. Без скобок C# не поймёт, где заканчивается выражение. Внутри $"..." тернарный оператор всегда нужно оборачивать в круглые скобки!
Вложенные тернарные операторы и почему их стоит избегать
Тернарный оператор можно вкладывать друг в друга. Технически это работает. Но на практике — не делай так.
❌ Плохо (нечитаемо)
int x = 75;
string level = x >= 90 ? "Отлично"
: x >= 75 ? "Хорошо"
: x >= 50 ? "Удовл."
: "Неуд.";
✅ Хорошо (читаемо)
string level;
if (x >= 90) level = "Отлично";
else if (x >= 75) level = "Хорошо";
else if (x >= 50) level = "Удовл.";
else level = "Неуд.";
Проблемы вложенных тернарных операторов:
- Читаемость страдает. Даже через 2 дня ты сам не поймёшь, что написал.
- Отладка усложняется. Нельзя поставить точку остановки на части выражения.
- Коллеги будут недовольны. Код пишется для людей, а не для компилятора.
💡 Золотое правило: не больше одного тернарного оператора в выражении. Если нужно больше — используй if-else или switch.
Читаемость кода: когда тернарный оператор уместен
Тернарный оператор делает код короче, но может испортить читаемость. Вот когда его стоит использовать:
✅ Когда тернарный уместен:
- Простое присваивание:
string gender = isMale ? "М" : "Ж"; - Console.WriteLine с выбором текста
- Возврат из простого метода:
static int Abs(int x) => x >= 0 ? x : -x; - Выбор форматирования:
$"Цена: {price}{isDiscount ? " (скидка!)" : ""}"
❌ Когда лучше if-else:
- Вложенные тернарные операторы
- Сложные условия с && или ||
- Ветки, где выполняются целые блоки кода
- Условия с побочными эффектами (запись в файл, отправка запроса)
// ✅ Присваивание
string greeting = hour < 12 ? "Доброе утро" : "Добрый день";
// ✅ Возврат из метода
static double GetTax(double price, bool isLuxury)
=> isLuxury ? price * 0.2 : price * 0.1;
// ✅ В строке вывода
Console.WriteLine($"Статус: {(isActive ? "Активен" : "Неактивен")}");
// ✅ Форматирование
string label = count == 1 ? "товар" : (count >= 2 && count <= 4 ? "товара" : "товаров");
// Но это уже на грани — лучше бы через if-else с return
Сводный пример — проверка скидки
Напишем программу, которая использует тернарный оператор в нескольких местах:
using System;
class Program
{
static void Main()
{
Console.Write("Введите сумму покупки: ");
double amount = Convert.ToDouble(Console.ReadLine());
Console.Write("Вы премиум-клиент? (да/нет): ");
bool isPremium = Console.ReadLine().Trim().ToLower() == "да";
// Тернарный для расчёта скидки
double discountRate = isPremium ? 0.2 : 0.05;
double discount = amount * discountRate;
double total = amount - discount;
// Тернарный для форматирования вывода
string discountLabel = discount > 0
? $"Скидка {discountRate * 100}%: -{discount:F2} руб."
: "Скидка не предоставлена";
Console.WriteLine();
Console.WriteLine("=".PadRight(40, '='));
Console.WriteLine($"Сумма: {amount:F2} руб.");
Console.WriteLine(discountLabel);
Console.WriteLine($"Итого: {total:F2} руб.");
Console.WriteLine("=".PadRight(40, '='));
}
}
Мини-тест
Проверь, как ты усвоил тернарный оператор.
Вопрос 1
int x = 10;
int y = 5;
int result = x > y ? x * 2 : y * 3;
Console.WriteLine(result);
Варианты: A) 10 B) 20 C) 15 D) 5
Вопрос 2
string name = "Анна";
bool isAdmin = false;
string label = isAdmin ? "Администратор" : name;
Console.WriteLine(label);
Варианты: A) Администратор B) Анна C) Ошибка компиляции
Вопрос 3
int a = 5, b = 10, c = 3;
int max = a > b ? (a > c ? a : c) : (b > c ? b : c);
Console.WriteLine(max);
Варианты: A) 5 B) 10 C) 3 D) Ошибка
Вопрос 4
Console.Write(5 > 3 ? "Да" : 42);
Варианты: A) Да B) 42 C) Ошибка компиляции
Задача
Задание: Конвертер температуры
Напиши программу, которая:
- Запрашивает у пользователя температуру (double)
- Запрашивает единицу измерения: C (Цельсий) или F (Фаренгейт)
- Конвертирует температуру в противоположную шкалу
- Выводит результат, используя тернарный оператор хотя бы в трёх местах
Формулы:
- F → C: (F - 32) * 5 / 9
- C → F: C * 9 / 5 + 32
Пример работы:
Введите температуру: 100
Шкала (C/F): C
100 °C = 212 °F
Что важно запомнить
условие ? значение_если_true : значение_если_false. Возвращает одно из двух значений.$"{(isActive ? "Да" : "Нет")}"Тест: 3.5: Тернарный оператор
5 вопросов