$ sudo teach IT
Модуль 3 · Условный оператор

Урок 3.5 — Тернарный оператор

Короткая запись if-else в одной строке. Красиво и опасно одновременно.

Бывает, что нужно присвоить переменной одно из двух значений в зависимости от условия. Конечно, можно написать if-else. Но есть способ короче. Тернарный оператор — это как if-else, но сжатый до одной строки и возвращающий значение. Сегодня мы научимся пользоваться этим мощным, но опасным инструментом.

❓

Синтаксис тернарного оператора

Тернарный оператор называется так, потому что он принимает три операнда. В C# он выглядит так:

Общая схема:

условие ? значение_если_true : значение_если_false

Пример: string result = age >= 18 ? "Взрослый" : "Ребёнок";

Как это работает:

  1. Вычисляется условие (оно должно быть bool)
  2. Если условие true — возвращается то, что после ?
  3. Если условие false — возвращается то, что после :
C# · Первый пример
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)
💡 Простое правило: если код в if и else — это одна строка, которая выбирает значение — можно тернарный. Если больше — используй if-else.
📝

Применение в присваивании

Самое частое применение тернарного оператора — присвоить переменной одно из двух значений:

C# · Присваивание с тернарным
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;
💡 Если результат тернарного оператора — bool, подумай, не упростится ли выражение. temperature > 25 ? true : false — это то же самое, что просто temperature > 25.
🖨️

Применение в Console.WriteLine и аргументах

Тернарный оператор можно использовать прямо внутри вызова метода, в аргументах, в интерполяции строк. Это делает код компактнее:

C# · Тернарный в выводе
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:

  • Вложенные тернарные операторы
  • Сложные условия с && или ||
  • Ветки, где выполняются целые блоки кода
  • Условия с побочными эффектами (запись в файл, отправка запроса)
C# · Хорошие примеры
// ✅ Присваивание
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
🛠️

Сводный пример — проверка скидки

Напишем программу, которая использует тернарный оператор в нескольких местах:

C# · Калькулятор скидки
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, '='));
    }
}
💡 Обрати внимание: мы использовали тернарный оператор дважды — для расчёта ставки скидки и для формирования строки. Оба случая простые и читаемые. Если бы логика расчёта скидки была сложнее — мы бы вынесли её в отдельный метод или if-else.
🧪

Мини-тест

Проверь, как ты усвоил тернарный оператор.

Вопрос 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) Ошибка компиляции

💡 Ответы: 1 — B (x > y → true, 10 * 2 = 20). 2 — B (isAdmin → false, возвращается name). 3 — B (вложенный тернарный, результат 10). 4 — C (типы разные: string и int, компилятор не может определить тип результата).
🎮

Задача

Задание: Конвертер температуры

Напиши программу, которая:

  1. Запрашивает у пользователя температуру (double)
  2. Запрашивает единицу измерения: C (Цельсий) или F (Фаренгейт)
  3. Конвертирует температуру в противоположную шкалу
  4. Выводит результат, используя тернарный оператор хотя бы в трёх местах

Формулы:

  • F → C: (F - 32) * 5 / 9
  • C → F: C * 9 / 5 + 32

Пример работы:

Введите температуру: 100
Шкала (C/F): C
100 °C = 212 °F
💡 Подсказка: используй тернарный для выбора формулы конвертации, для формирования строки вывода (℃ / ℉) и для сообщения об ошибке при неверной шкале.
📌

Что важно запомнить

1️⃣
Синтаксис: условие ? значение_если_true : значение_если_false. Возвращает одно из двух значений.
2️⃣
Тернарный — не замена if-else. Он для выбора значения, а не для выполнения блоков кода.
3️⃣
Избегай вложенных тернарных операторов. Они нечитаемы. Если больше одного условия — используй if-else.
4️⃣
В интерполяции используй скобки: $"{(isActive ? "Да" : "Нет")}"
5️⃣
Типы значений должны совпадать. Нельзя смешивать string и int в тернарном операторе без приведения.

Тест: 3.5: Тернарный оператор

5 вопросов

Switch

Premium