1. Введение
Представьте, что вы — бариста популярной кофейни. К вам приходит посетитель и называет один из пяти любимых напитков. Вы не устраиваете философский разбор, а быстро смотрите в меню и реагируете: «Капучино? Конечно! Вот ваш капучино!». Если бы вы каждую позицию проверяли через отдельный if, ваш код выглядел бы как стопка чашек после обеденного наплыва — громоздко и не очень удобно.
Оператор switch позволяет элегантно проверять значение переменной и выполнять разные действия в зависимости от результата. Работает он только с определёнными типами данных (о них — чуть ниже), но в большинстве пользовательских меню, простых команд или распознавании статусов это идеальный инструмент.
2. Синтаксис классического switch в C#
Вот минимальная блок-схема работы:
switch (Выражение) {
case Значение1:
// действия
break;
case Значение2:
// действия
break;
...
default:
// действия по умолчанию
break;
}
Пример 1: классическое меню
Console.WriteLine("Выберите напиток: 1 - Кофе, 2 - Чай, 3 - Какао");
string input = Console.ReadLine();
int choice = int.Parse(input);
switch (choice)
{
case 1:
Console.WriteLine("Вы выбрали кофе. Отличный выбор!");
break;
case 2:
Console.WriteLine("Чай — тоже хорошо.");
break;
case 3:
Console.WriteLine("Какао — для ценителей уюта!");
break;
default:
Console.WriteLine("Такого напитка нет в меню.");
break;
}
- Блок switch проверяет choice на равенство значениям после case.
- После каждого варианта обязательно пишется break; — иначе выполнение перейдет и на следующий case (об этом чуть ниже).
- Блок default — как else; он сработает, если не совпал ни один case.
Как работает switch внутри? — Пошагово
- Сначала вычисляется выражение в скобках после switch (в нашем примере — переменная choice).
- Программа сравнивает его с каждым указанным значением (case) по очереди.
- Если совпало — выполняются инструкции этого блока. Затем встречается break, и программа выходит из блока switch.
- Если не совпало ни с одним case, выполняется блок default (если он есть).
Визуальная схема
| Значение переменной | case 1 | case 2 | case 3 | default |
|---|---|---|---|---|
| 1 | + | |||
| 2 | + | |||
| 3 | + | |||
| другое | + |
«+» — этот блок выполняется
3. Какие типы поддерживает классический switch?
В классическом синтаксисе (то есть, без "Pattern Matching" и новых фишек, о которых поговорим позже!) switch поддерживает:
- Простые целочисленные типы (int, byte, char, long, short, sbyte, ushort, uint, ulong)
- Строки (string)
- Перечисления (enum)
- Символы (char)
Пример 2: переключение по строкам
Console.WriteLine("Выберите команду: start, stop, pause");
string command = Console.ReadLine();
switch (command)
{
case "start":
Console.WriteLine("Программа запущена!");
break;
case "stop":
Console.WriteLine("Программа остановлена.");
break;
case "pause":
Console.WriteLine("Программа на паузе.");
break;
default:
Console.WriteLine("Неизвестная команда.");
break;
}
4. Почему нужен break и что будет, если его забыть?
Самый популярный программистский глюк среди новичков — забыть break; внутри case. Давайте разберёмся, что будет, если его пропустить.
Пример 3: падение в следующий блок (fall-through)
int day = 2;
switch (day)
{
case 1:
Console.WriteLine("Понедельник");
break;
case 2:
Console.WriteLine("Вторник");
case 3:
Console.WriteLine("Среда");
break;
default:
Console.WriteLine("Неизвестный день");
break;
}
Что произойдёт?
- На входе day = 2.
- Сначала выполнится строка: "Вторник"
- Нет break — выполнение перейдёт сразу в case 3 и выполнит: "Среда"
- Затем встретится break; — выход.
На экране увидим:
Вторник
Среда
Это типичная ошибка!
- Если вам нужно выполнить ОДНО действие, ставьте break; в каждом case.
- Если (редко) вы хотите, чтобы некоторые варианты выполняли одну и ту же логику, можно их «склеить» (см. ниже).
5. Группировка значений case
Иногда несколько значений должны вести себя одинаково. Зачем копировать один и тот же код?
Пример 4: одинаковая реакция на несколько case
char grade = 'B';
switch (grade)
{
case 'A':
case 'B':
case 'C':
Console.WriteLine("Зачёт!");
break;
case 'D':
case 'E':
Console.WriteLine("Есть куда расти.");
break;
default:
Console.WriteLine("Неверная оценка.");
break;
}
Что происходит?
- Если grade — это 'A', 'B' или 'C', сработает первый блок: "Зачёт!".
- Если 'D' или 'E' — второй блок.
- Если другое — default.
6. Что можно, а что нельзя в классическом switch
Можно:
- Использовать литералы (константы) в case, например: case 1:, case 'A':, case "стоп":.
- Сравнивать enum (перечисления).
- Опускать default, но обычно он полезен.
Нельзя:
- Использовать переменные в case (только константы).
- Сравнивать по диапазонам (case >= 5:, case x > 10: — так нельзя!).
- Использовать double, float и другие вещественные значения — только целые, string, char, enum.
- Писать несколько значений через запятую в одном case (case 1, 2: так делать нельзя; пишите несколько case подряд).
7. Особенности и типичные ошибки
В реальных проектах switch часто используют для меню, обработки статусов, команд, кодов ошибок и ещё тысячи задач. Но, как и у любого инструмента, есть нюансы.
Типичные ошибки:
- Пропущенный break (о чём уже говорили).
- Неправильный тип switch-выражения (например, попытка использовать double).
- Несовпадение регистра строк (case "Start": не совпадёт со "start") — строки сравниваются с учётом регистра!
- Необработанное значение (забыли default, пользователь ввёл не то).
Ловушка с вложенными switch-ами
Хотя такой код можно встретить, чаще всего он плохо читается. Если ловите себя на том, что вкладываете switch в switch, возможно, пора вынести ваш код в отдельный метод или даже применить ООП/enum/массив.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ