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. Вложенные тернарные операторы — осторожно!
Тернарный оператор можно вкладывать друг в друга (в каждой из веток может быть ещё один тернарник). Но… от этого обычно болит голова, особенно у того, кто будет читать код после вас (даже если это вы через 2 дня).
Пример: определение категории по возрасту
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);
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ