Условные операторы в C#: if, else, switch и тернарный оператор

Условные операторы в C#: if, else, switch и тернарный оператор Полезное

Условный оператор в C# — это конструкция, которая выполняет разный код в зависимости от условия типа bool: если условие истинно (true), идет одна ветка, если ложно (false) — другая или никакая. В C# их два вида: инструкции (if/else, оператор switch) управляют тем, какой блок кода выполнится, а условные выражения (тернарный ?:, switch-выражение, ??) вычисляют значение, которое можно сразу присвоить переменной.

Ниже — каждая конструкция с рабочим примером, типичные ошибки новичков и таблица «какую конструкцию выбрать». Синтаксис актуален для C# 14 (.NET 10), все примеры проверены на .NET SDK 10.0.401 23.09.2026; где возможность появилась позже C# 1, версия указана.

Мини-словарь, чтобы не путаться дальше:

Термин Что это Пример
Условие Выражение, результат которого bool age >= 18
Инструкция (statement) Действие, ничего не возвращает if (...) { ... }
Выражение (expression) Вычисляется в значение age >= 18 ? "да" : "нет"
Шаблон (pattern) Проверка формы значения: тип, диапазон, свойства is int n, > 0 and < 10

if, else и else if: базовое ветвление

Сначала полный пример — программа оценивает балл за тест. Код рассчитан на консольный проект .NET 6 и новее (top-level statements без класса Program появились в C# 9, а неявные using, на которые опираются остальные примеры, — в шаблоне .NET 6):

using System;

int score = 73;

if (score >= 90)
{
    Console.WriteLine("Отлично");
}
else if (score >= 70)
{
    Console.WriteLine("Хорошо");
}
else if (score >= 50)
{
    Console.WriteLine("Удовлетворительно");
}
else
{
    Console.WriteLine("Не сдано");
}

Вывод:

Хорошо

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

  • if (score >= 90) — условие в круглых скобках обязательно. 73 >= 90 ложно, блок пропускается.
  • else if (score >= 70) — проверяется, только если все предыдущие условия ложны. 73 >= 70 истинно, печатается «Хорошо».
  • После первой сработавшей ветки остальные else if и else не проверяются вообще. Поэтому порядок важен: если поставить score >= 50 первым, балл 95 получит «Удовлетворительно».
  • else без условия — ветка «во всех остальных случаях». Она необязательна.

Отдельного elseif или then, как в Visual Basic или Pascal, в C# нет: else if — это else, за которым идет следующий if.

Фигурные скобки и вложенные if

Для одной инструкции скобки {} можно опустить, но вторая строка, добавленная «в ветку» без скобок, выполнится всегда. Надежнее ставить скобки всегда.

Вложенный if нужен, когда вторая проверка имеет смысл только после первой:

bool isLoggedIn = true;
bool isAdmin = false;

if (isLoggedIn)
{
    if (isAdmin)
    {
        Console.WriteLine("Панель администратора");
    }
    else
    {
        Console.WriteLine("Личный кабинет");
    }
}
else
{
    Console.WriteLine("Войдите в систему");
}
// Вывод: Личный кабинет

Без скобок else относится к ближайшему if сверху, а не к тому, под которым он выровнен отступом.

Логические операторы в условиях

Условия комбинируют операторами && (и), || (или), ! (не). && и || работают с коротким замыканием: правая часть не вычисляется, если результат уже ясен по левой. На этом строится безопасная проверка на null:

string? name = null;

if (name != null && name.Length > 3)
{
    Console.WriteLine("Длинное имя");
}
else
{
    Console.WriteLine("Имени нет или оно короткое");
}
// Вывод: Имени нет или оно короткое

Если заменить && на одиночный &, обе части вычислятся всегда, и name.Length при name == null выбросит NullReferenceException.

Типичные ошибки в if

Ошибка 1. Число вместо условия. В C и C++ if (count) означает «если не ноль». В C# условие обязано иметь тип bool:

int count = 1;
if (count) // ошибка компиляции
{
    Console.WriteLine("Есть элементы");
}

Результат: программа не компилируется, ошибка CS0029 «Cannot implicitly convert type ‘int’ to ‘bool’». Исправление — явное сравнение: if (count != 0) или if (count > 0).

Ошибка 2. Точка с запятой после условия.

int x = 5;
if (x > 10);
{
    Console.WriteLine("Больше 10");
}

Результат: код компилируется с предупреждением CS0642 «Possible mistaken empty statement», а «Больше 10» печатается при любом x. ; закончил if, и блок в скобках выполняется всегда. Исправление — убрать ; после if (x > 10).

switch: выбор из нескольких значений

Оператор switch удобен, когда одну переменную сравнивают с набором конкретных значений.

string day = "сб";

switch (day)
{
    case "сб":
    case "вс":
        Console.WriteLine("Выходной");
        break;
    case "пт":
        Console.WriteLine("Короткий день");
        break;
    default:
        Console.WriteLine("Рабочий день");
        break;
}
// Вывод: Выходной

Разбор:

  • case "сб": и case "вс": подряд без кода между ними — несколько меток на одну ветку. Так в C# записывается «или».
  • break завершает ветку. В отличие от C/C++, «проваливания» из непустой ветки в следующую в C# нет: если забыть break (или return, throw, goto case/goto default, а внутри цикла — continue), компилятор выдаст ошибку CS0163 «Control cannot fall through from one case label (‘case «сб»:’) to another» — в скобках компилятор подставляет метку ветки.
  • default — аналог финального else, срабатывает, если ни один case не подошел.

Начиная с C# 7 в case можно писать не только константы, но и шаблоны с дополнительным условием when:

object input = 15;

switch (input)
{
    case int n when n > 10:
        Console.WriteLine($"Целое больше 10: {n}");
        break;
    case int n:
        Console.WriteLine($"Целое: {n}");
        break;
    case string s:
        Console.WriteLine($"Строка длиной {s.Length}");
        break;
    default:
        Console.WriteLine("Другой тип");
        break;
}
// Вывод: Целое больше 10: 15

Здесь case int n одновременно проверяет тип и объявляет переменную n уже нужного типа. Ветки проверяются сверху вниз, поэтому более узкий случай (when n > 10) стоит выше общего.

switch-выражение и pattern matching

Switch-выражение (C# 8) — компактная форма, которая возвращает значение. В C# 9 к нему добавились реляционные шаблоны (<, >=) и комбинаторы and, or, not:

static string Describe(int temperature) => temperature switch
{
    < 0 => "мороз",
    0 => "ноль",
    > 0 and <= 20 => "прохладно",
    _ => "тепло"
};

Console.WriteLine(Describe(-5));
Console.WriteLine(Describe(0));
Console.WriteLine(Describe(15));
Console.WriteLine(Describe(28));

Вывод:

мороз
ноль
прохладно
тепло

Отличия от оператора switch:

  • Переменная стоит перед словом switch, ветки разделяются запятыми, case и break не нужны.
  • Каждая ветка — это выражение, а не набор инструкций. Все ветки должны давать совместимый тип.
  • _ — шаблон «все остальное», аналог default. Если он не нужен, компилятор все равно проверяет полноту: при непокрытых значениях выдается предупреждение, а если такое значение придет во время работы, будет выброшено исключение SwitchExpressionException.

Шаблоны работают и в обычном if через оператор is:

object value = 42;

if (value is int number && number > 10)
{
    Console.WriteLine($"Число {number}");
}

// Вывод: Число 42

Проверки x is null и x is not null (вторая — с C# 9) не зависят от перегруженного == в пользовательских типах.

Тернарный оператор и оператор ??

Тернарный оператор условие ? значение1 : значение2 — короткая замена if/else, когда нужно выбрать одно из двух значений:

int age = 17;
string status = age >= 18 ? "взрослый" : "несовершеннолетний";
Console.WriteLine(status); // несовершеннолетний

Вложенные тернарные (a ? b : c ? d : e) работают, но читаются хуже switch-выражения.

Оператор ?? (null-coalescing) возвращает левый операнд, если он не null, иначе правый. ??= (C# 8) присваивает значение, только если переменная равна null:

string? nickname = null;
string shown = nickname ?? "Гость";
Console.WriteLine(shown); // Гость

nickname ??= "user42";
Console.WriteLine(nickname); // user42

?? проверяет только null. Пустая строка "" — не null, поэтому "" ?? "Гость" вернет "". Для проверки пустых строк нужен string.IsNullOrEmpty.

Какую конструкцию выбрать

Задача Что взять Когда иначе
Одно условие, выполнить действие if —
Два варианта действий if/else Если выбирается значение — тернарный ?:
Несколько диапазонов или разных условий if - else if - else Если все условия про одну переменную — switch-выражение с шаблонами
Одна переменная, набор конкретных значений, в ветках действия оператор switch Если в ветках только значения — switch-выражение
Получить значение по набору вариантов switch-выражение Для 2 вариантов проще ?:
Значение по умолчанию вместо null ??, ??= Для пустых строк — string.IsNullOrEmpty
Проверка типа и приведение за один шаг is Тип имя Для многих типов — switch по шаблонам

Главный критерий: если нужно сделать что-то в зависимости от условия — инструкция (if, switch); если нужно получить значение — выражение (?:, switch-выражение, ??).

Выводы

  • Условие в C# всегда имеет тип bool: if (count) с числом не компилируется, нужно явное сравнение.
  • В цепочке if - else if - else выполняется только первая истинная ветка, поэтому порядок условий определяет результат.
  • В операторе switch нет проваливания из непустой ветки: каждую ветку завершает break, return, throw или goto (goto case, goto default).
  • Switch-выражение (C# 8+) и шаблоны (is, <, and, or, not) заменяют длинные лестницы else if, когда проверяется одна переменная.
  • Тернарный ?: и ?? — выражения для выбора значения, а не для выполнения действий.

Где применяется / связь с практикой

Условные конструкции есть в любой программе на C#: проверка ввода, логика игры на Unity, обработка статусов заказа в веб-API на ASP.NET Core.

Освойте тему на практике

Системно освоить синтаксис C#, ООП и первые приложения с разбором кода от преподавателей можно на курсе «C# Developer. Basic». Посмотреть формат обучения и задать вопросы практикующим разработчикам можно на бесплатных открытых уроках.

FAQ

Можно ли в switch сравнивать строки и диапазоны чисел?
Да. Строки можно сравнивать в case со времен C# 1, а диапазоны вида > 0 and <= 20 — с C# 9 через реляционные шаблоны.

Что быстрее — if/else или switch?
Для нескольких веток разница несущественна, а для большого набора констант компилятор может построить таблицу переходов или хеш-поиск по строкам. Выбирать стоит по читаемости, а производительность при необходимости измерять.

Есть ли в C# оператор elseif или unless?
Нет. Используется else if из двух слов, а вместо unless — if с отрицанием: if (!условие) или if (x is not null).

OTUS Журнал