Оператор switch в C#: примеры и лучшие практики
Кратко
Кратко: оператор switch в C# удобен для выбора одной ветки выполнения по значению переменной. В статье показаны примеры со строками и числами, поведенческие шаблоны, типичные ошибки и альтернативы.
В приложениях часто требуется выполнять разные действия в зависимости от условий. Для таких задач используют условные конструкции: if, if-else, switch и другие. Оператор switch помогает удобно организовать набор вариантов, особенно когда нужно сравнить единственное значение с несколькими вариантами.
Ниже мы пройдём шаг за шагом, как сделать простой пример в C#, разберём числа и строки в switch, добавим default, рассмотрим альтернативы и дадим практические рекомендации для разработки и тестирования.
Зачем и когда использовать switch
Оператор switch — это удобный выбор, когда:
- нужно сравнить одно значение с множеством фиксированных вариантов;
- хочется читаемо представить большое число ветвлений;
- важна явная обработка разных случаев (включая default).
Когда switch не подходит:
- логика ветвлений зависит от сложных условий (диапазоны, составные проверки);
- требуется поведение на основе типов объектов (полиморфизм лучше);
- количество возможных значений велико и динамично — лучше использовать словарь или базу данных.
Важно: в современных версиях C# появились расширенные формы switch (pattern matching, switch expressions), они позволяют писать компактнее и безопаснее.
Быстрый пример: консольное приложение в Visual Studio
- Откройте Visual Studio и выберите «Создать новый проект».
- Выберите шаблон «Консольное приложение» и нажмите Дальше.
- Укажите имя проекта и папку для сохранения, затем нажмите Дальше.
- Оставьте целевую платформу по умолчанию и нажмите «Создать». Visual Studio откроет шаблон с методом Main и примером Hello World.
Следующие примеры предполагают базовое консольное приложение с методом Main.
Пример 1 — switch с строками (вариант пользователя)
Покажем простой сценарий, где пользователь выбирает категорию блюд.
// Отображаем список опций для пользователя
Console.WriteLine("Выберите опцию:");
Console.WriteLine("1. Фрукты");
Console.WriteLine("2. Основные блюда");
Console.WriteLine("3. Десерты");
Console.WriteLine("");
// Запрос ввода
Console.Write(">> ");
string meals = Console.ReadLine().ToLower();Добавим оператор switch, который сравнивает строку meals:
switch (meals)
{
case "фрукты":
Console.WriteLine("Фрукты: яблоки, апельсины, бананы.");
break;
case "основные блюда":
Console.WriteLine("Основные блюда: стейк, лосось, ризотто.");
break;
case "десерты":
Console.WriteLine("Десерты: шоколадный торт, яблочный пирог, мороженое.");
break;
default:
Console.WriteLine("Неизвестная опция. Введите Фрукты, Основные блюда или Десерты.");
break;
}Примечания по реализации:
- Приведение к нижнему регистру (ToLower()) помогает сравнивать независимо от регистра; учтите особенности культуры (CultureInfo) при локализации.
- Нельзя полагаться на точное совпадение вводимых строк — добавьте валидацию или подсказки для пользователя.
Пример 2 — switch по числам (ввод числа)
Иногда удобнее дать пользователю выбрать номер. В этом случае нужно безопасно преобразовать ввод в число.
int result = 1;
try
{
// Попытка конвертировать ввод в число
result = Int32.Parse(meals);
}
catch (FormatException)
{
// Если ввод неверный — предупредить и завершить программу
Console.WriteLine($"'{meals}' имеет неверный формат. Введите число.");
System.Environment.Exit(1);
}Теперь используем switch по числу:
switch (result)
{
case 1:
Console.WriteLine("Вы выбрали опцию 1 (Фрукты): яблоки, апельсины, бананы.");
break;
case 2:
Console.WriteLine("Вы выбрали опцию 2 (Основные блюда): стейк, лосось, ризотто.");
break;
case 3:
Console.WriteLine("Вы выбрали опцию 3 (Десерты): шоколадный торт, яблочный пирог, мороженое.");
break;
default:
Console.WriteLine("Введённое число не входит в список доступных опций.");
break;
}Как добавить default
Default — это резервный вариант, который сработает, если ни одно case не совпало. В примерах выше default уже используется. Он полезен для ввода вне диапазона или неожиданных значений.
// Пример со default уже показан: он выведет сообщение о недопустимом вариантеРасширенные возможности switch в современных версиях C
C# поддерживает pattern matching и switch expressions, которые полезны, когда нужно проверить тип или составное условие.
Пример switch expression (C# 8+):
string GetCategoryMessage(int option) => option switch
{
1 => "Фрукты: яблоки, апельсины, бананы.",
2 => "Основные блюда: стейк, лосось, ризотто.",
3 => "Десерты: шоколадный торт, яблочный пирог, мороженое.",
_ => "Неизвестная опция"
};Pattern matching example:
object input = GetInput();
switch (input)
{
case int i when i > 0:
Console.WriteLine("Положительное число");
break;
case string s:
Console.WriteLine($"Строка длиной {s.Length}");
break;
case null:
Console.WriteLine("Вход = null");
break;
default:
Console.WriteLine("Другой тип данных");
break;
}Эти конструкции позволяют писать выразительный и при этом безопасный код.
Типичные ошибки и как их избежать
Important: будьте внимательны к следующим моментам:
- Использование ToLower() без учёта культуры может дать неожиданные результаты. Для безопасной нормализации используйте ToLowerInvariant() или методы с CultureInfo.
- Попытка «провалиться» через case в C# невозможна без goto; помните о break — это часто нужно.
- NullReference: если значение, передаваемое в switch, может быть null, добавьте проверку или обработайте case null.
- Чтение пользовательского ввода всегда валидируйте: Parse может выбросить исключение — используйте TryParse.
Пример безопасной валидации:
if (!Int32.TryParse(meals, out int option))
{
Console.WriteLine("Пожалуйста, введите корректное число.");
return;
}Когда лучше использовать альтернативы
Альтернативы switch:
- if / else if — когда проверки сложные или зависят от диапазонов;
- Dictionary
или Dictionary — когда нужно ассоциировать поведение с ключом динамически; - Полиморфизм (паттерны Strategy / Command) — когда разные варианты имеют собственную реализацию и изменения расширяют систему.
Пример с словарём:
var actions = new Dictionary
{
[1] = () => Console.WriteLine("Фрукты"),
[2] = () => Console.WriteLine("Основные блюда"),
[3] = () => Console.WriteLine("Десерты")
};
if (actions.TryGetValue(option, out var action)) action();
else Console.WriteLine("Неизвестная опция"); Преимущество словаря — лёгкое расширение без изменения большого switch.
Руководство по выбору: краткая методология
- Если нужно сравнить единичное значение с фиксированными литералами — используйте switch.
- Если проверки сложные или зависят от диапазонов — if/else.
- Если поведение меняется динамически или растёт число вариантов — рассмотрите Dictionary или полиморфизм.
- Для компактной и выразительной логики используйте switch expressions и pattern matching.
Рольовые чек-листы (разработчик, тестировщик, ревьюер)
Разработчик:
- Нормализовал ввод (Trim, ToLowerInvariant при необходимости).
- Обработал null и неверный формат.
- Использовал break / return / switch expression корректно.
- Добавил unit-тесты для каждого case и default.
Тестировщик:
- Проверил строки в разных регистрах (верхний/нижний).
- Проверил поведение при null/пустой строке.
- Проверил невалидный ввод (символы, буквы при ожидании числа).
- Проверил граничные значения и типы данных.
Ревьюер кода:
- Оценил читаемость switch vs альтернативы.
- Проверил отсутствие дублирования кода в ветках.
- Подтвердил корректное логирование и пользовательские сообщения.
Критерии приёмки
- Программа корректно обрабатывает допустимые варианты (1,2,3 или соответствующие строки).
- Обработка недопустимого ввода ведёт к понятному сообщению для пользователя и не вызывает исключений.
- Все добавленные тесты проходят, покрытия для веток достаточное.
Тест-кейсы / приёмочные сценарии
- Ввести “1” — ожидаемый вывод: список фруктов.
- Ввести “Фрукты” (в разных регистрах) — выдача списка фруктов.
- Ввести “4” или “не число” — вывод сообщения об ошибке.
- Ввести пустую строку — вывод подсказки по вводу.
Короткий глоссарий
- switch: конструкция для выбора ветки по значению.
- case: вариант внутри switch, сравниваемый со значением.
- default: ветка по умолчанию при отсутствии совпадений.
- pattern matching: расширенная проверка с шаблонами в C#.
Ментальные модели и эвристики
- Представляйте switch как таблицу «вход → действие». Если таблица статична и небольшая — switch уместен.
- Если действия зависят от состояния объекта — думайте о делегировании ответственности в отдельные классы (полиморфизм).
Decision flowchart (mermaid)
flowchart TD
A[Нужно сравнить значение?] --> B{Значения фиксированные и несложные?}
B -- Да --> C[Использовать switch]
B -- Нет --> D{Значения динамические или поведение разнообразно?}
D -- Да --> E[Dictionary / Полиморфизм]
D -- Нет --> F[if / else]Безопасность и локализация
- Для сообщений пользователю используйте ресурсы локализации (resx) вместо строк в коде.
- Учтите особенности культуры при сравнении строк (регистрозависимость, символы).
Заключение
Оператор switch — удобный инструмент для выбора одной из множества веток по значению. Он даёт чистую и понятную структуру, особенно для статических наборов вариантов. Для более сложной логики рассмотрите switch expressions, pattern matching, словари или полиморфизм. Включайте валидацию ввода, юнит-тесты и обработку default, чтобы избежать ошибок во время выполнения.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone