← Все вопросы

Что такое тернарный оператор в C# и как им пользоваться?

Задан 14 дней назад269 просмотров2 ответа
2

Встретил в чужом коде строку вида var x = a > b ? a : b; и не сразу понял, что происходит. Это какой-то сокращённый if? Как правильно его читать и есть ли смысл им заменять обычный if-else? И ещё видел рядом ?? — это то же самое или другое?

2 ответа

8
✓ Принятый ответ — помог автору

Это тернарный (условный) оператор — единственный оператор в C# с тремя операндами. Читается так: условие ? значение_если_true : значение_если_false.

int a = 5, b = 9;
int max = a > b ? a : b;   // если a>b вернёт a, иначе b -> 9

По сути это компактная замена короткого if-else, который возвращает значение:

// вместо этого
int max;
if (a > b) max = a; else max = b;

// пишем это
int max = a > b ? a : b;

Главное отличие от обычного if: тернарный — это выражение, его результат можно присвоить, передать в метод, вставить в строку. Поэтому он не подходит, когда в ветках нужно выполнить действия (несколько строк, побочные эффекты) — там оставляй обычный if.

Вложенность технически возможна, но читается тяжело:

string grade = score >= 90 ? "A"
             : score >= 75 ? "B"
             : score >= 60 ? "C"
             : "F";

Работает, но злоупотреблять не стоит: вложенные тернарники быстро превращаются в ребус, и тут уже лучше switch expression. Правило простое — одно условие в строку читается отлично, три и больше уже спорно.

Родственник ?? (null-coalescing). Он не про логику true/false, а про null: a ?? b вернёт a, если он не null, иначе b.

string name = input ?? "гость";   // если input == null -> "гость"

Это не тернарный оператор, но решает похожую задачу «выбрать одно из двух» именно для случая с null, и читается чище, чем input != null ? input : "гость".

2

Маленькое, но важное дополнение: обе ветки тернарного оператора должны быть совместимы по типу. Например, cond ? 1 : "text" не скомпилируется — int и string не сводятся к общему типу.

И ещё есть ??= (null-coalescing assignment): x ??= y; присвоит y переменной x, только если x сейчас null. Удобно для ленивой инициализации: _cache ??= LoadCache();.

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект