Несколько вариантов в одном case оператора switch в C# — как правильно?
Объединение нескольких case с помощью pattern matching в C# 8.0+
Вы абсолютно правы — в современных версиях C# (начиная с 8.0) появился более элегантный способ обработки нескольких значений в одном блоке switch. Это называется pattern matching (сопоставление с образцом). Давайте разберём несколько подходов от простого к сложному.
1. Классический способ (работает во всех версиях)
Ваш текущий код абсолютно корректен. Это стандартный подход, который используется десятилетиями. Он надёжен и понятен:
int day = 6;
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
Console.WriteLine("Будний день");
break;
case 6:
case 7:
Console.WriteLine("Выходной");
break;
default:
Console.WriteLine("Неверный день");
break;
}
Минус — многословность. Но если вам важна совместимость со старыми версиями C# (до 7.0), это лучший выбор.
2. Pattern matching с оператором "or" (C# 9.0+)
Начиная с C# 9.0, вы можете использовать логический оператор or прямо в case:
int day = 6;
switch (day)
{
case 1 or 2 or 3 or 4 or 5:
Console.WriteLine("Будний день");
break;
case 6 or 7:
Console.WriteLine("Выходной");
break;
default:
Console.WriteLine("Неверный день");
break;
}
Это гораздо компактнее и читаемее. Обратите внимание: or — это ключевое слово, а не логический оператор ||. Его можно использовать только в контексте pattern matching.
3. Switch-выражение (C# 8.0+) — самый лаконичный вариант
Если вам нужно просто вернуть значение, используйте switch-выражение. Это современный функциональный подход:
int day = 6;
string result = day switch
{
1 or 2 or 3 or 4 or 5 => "Будний день",
6 or 7 => "Выходной",
_ => "Неверный день"
};
Console.WriteLine(result);
Здесь _ — это аналог default. Switch-выражения обязаны быть исчерпывающими (покрывать все возможные значения), иначе компилятор выдаст предупреждение.
4. Pattern matching с диапазонами (для последовательных значений)
Если ваши значения идут подряд, можно использовать диапазоны:
int day = 6;
string result = day switch
{
>= 1 and <= 5 => "Будний день",
6 or 7 => "Выходной",
_ => "Неверный день"
};
Обратите внимание на and — это тоже ключевое слово для pattern matching. Такой подход особенно полезен, когда значений много (например, от 1 до 100).
5. Когда использовать какой подход?
- Классический switch — если код должен работать на старых версиях .NET Framework (до 4.8).
- Switch с "or" — если вам нужен привычный синтаксис switch-case, но более компактный.
- Switch-выражение — для современных проектов на .NET Core/5+, особенно если вы используете функциональный стиль.
- Диапазоны — когда значения образуют непрерывный интервал.
Лично я рекомендую использовать switch-выражения для новых проектов — они делают код чище и снижают вероятность ошибок (например, забытого break).
Важно помнить: если вы используете or или switch-выражения, убедитесь, что ваша версия C# поддерживает эти функции. Для .NET 6+ и Visual Studio 2022 все описанное работает без дополнительных настроек.
Альтернативный подход: использование словаря (Dictionary) для маппинга
Если ваша логика становится сложнее (например, разные дни требуют разных действий, а не просто возврата строки), можно использовать словарь с делегатами. Это особенно полезно, когда количество вариантов велико или они динамически загружаются.
var dayActions = new Dictionary<int, Action>
{
{ 1, () => Console.WriteLine("Понедельник — тяжёлый день") },
{ 2, () => Console.WriteLine("Вторник — рабочий") },
{ 3, () => Console.WriteLine("Среда — маленькая пятница") },
{ 4, () => Console.WriteLine("Четверг — почти пятница") },
{ 5, () => Console.WriteLine("Пятница — развратница") },
{ 6, () => Console.WriteLine("Суббота — выходной!") },
{ 7, () => Console.WriteLine("Воскресенье — отдых") }
};
int day = 6;
if (dayActions.TryGetValue(day, out var action))
action();
else
Console.WriteLine("Неверный день");
Преимущества этого подхода:
- Легко добавлять/удалять варианты без изменения структуры switch.
- Можно хранить маппинг в конфигурации или базе данных.
- Удобно для тестирования — словарь можно подменять.
Недостаток — код становится менее очевидным для новичков. Используйте этот подход, когда switch-case начинает разрастаться и нарушать принцип единственной ответственности (Single Responsibility).