JavaRush /Курсы /C# SELF /switch-выражения и н...

switch-выражения и новые паттерны

C# SELF
10 уровень , 5 лекция
Открыта

1. Введение

Вы уже умеете писать такой код:

switch (color)
{
    case "red":
        Console.WriteLine("Стоп!");
        break;
    case "yellow":
        Console.WriteLine("Ждите...");
        break;
    case "green":
        Console.WriteLine("Можно идти!");
        break;
    default:
        Console.WriteLine("А это что за цвет?");
        break;
}

Но что если мы хотим присвоить переменной разное значение в зависимости от входного параметра, например, вернуть строку, основанную на числе из функции? До появления switch-выражений приходилось городить вот такие конструкции:

string meaning;
switch (number)
{
    case 42:
        meaning = "Ответ на главный вопрос жизни, вселенной и вообще всего";
        break;
    case 7:
        meaning = "Счастливое число";
        break;
    default:
        meaning = "Обычное число";
        break;
}

Как-то не слишком элегантно для языка XXI века, правда? Хочется сразу вернуть значение, как это обычно бывает в функциональных языках.

Вот тут и появляются switch-выражения — одна из самых красивых (и свежих) возможностей C#, начиная с версии 8.0.

2. switch-выражения: синтаксис, который хочется обнять

Сравним: оператор и выражение
Классический switch — это statement ("оператор"), а switch-выражение — это expression, то есть оно вычисляет значение и его можно сразу присвоить переменной или вернуть из метода.

Структура switch-выражения:


var result = value switch
{
    pattern1 => expression1,
    pattern2 => expression2,
    _       => defaultExpression // "подчёркивание" - это "иначе"
};
Синтаксис switch-выражения

Например:

int number = 42;
string meaning = number switch
{
    42 => "Ответ на главный вопрос жизни, вселенной и вообще всего",
    7  => "Счастливое число",
    _  => "Обычное число"
};
Console.WriteLine(meaning); // => Ответ на главный вопрос жизни, вселенной и вообще всего

Всё лаконично, читаемо, никакой портянки кода, ни одного break;.

Обратите внимание: подчёркивание _ — это "поймать все остальные случаи", аналог default.

3. switch-выражения и паттерны: как они сочетаются

Вот где начинается настоящее веселье. В switch-выражениях можно использовать не только обычные значения, но и паттерны: проверки по диапазону, типу, свойствам объектов, деконструкции (разбиении объекта на его части), и даже combinatorial patterns (and, or, not).

Примеры паттернов в switch-выражении

Константные паттерны
Это то, что мы выше уже делали: сравнение с 42, 7 и так далее.

Диапазоны и сравнения

int age = 17;
string category = age switch
{
    < 18 => "Несовершеннолетний",
    >= 18 and <= 65 => "Взрослый",
    > 65 => "Пожилой человек",
    _ => "Неизвестная возрастная категория"
};
Console.WriteLine(category);

Кстати, обратите внимание — можно использовать несколько условий вместе! C# становится всё выразительнее.

Типовые паттерны (Type Patterns)

Допустим, у нас есть объект, который может быть разного типа (например, object value;). Мы можем обработать разные типы вот так:

object value = 3.14;
string description = value switch
{
    int i => $"Целое число: {i}",
    double d => $"Дробное число: {d:F2}",
    string s => $"Это строка: '{s}'",
    null => "null!",
    _ => "Что-то другое"
};
Console.WriteLine(description); // => Дробное число: 3.14

Связанные паттерны (Property Patterns и Positional Patterns)

С C# 8 и далее мы можем проверять значения свойств прямо в switch-выражении.

Пример с объектом

public class User
{
    public string Name { get; set; }
    public int Age { get; set; }
}

User user = new User { Name = "Анна", Age = 17 };
string welcome = user switch
{
    { Age: < 18 } => $"Здравствуй, {user.Name}! Ты подросток.",
    { Age: >= 18 and <= 65 } => $"Привет, {user.Name}! Взрослая жизнь прекрасна.",
    { Age: > 65 } => $"Добро пожаловать, {user.Name}! Вам всегда рады.",
    _ => "Неизвестный возраст"
};
Console.WriteLine(welcome);

Здесь в фигурных скобках { Age: < 18 } — это property pattern, то есть мы проверяем не весь объект, а только его свойство.

4. Новые паттерны C# 11-14

C# стремится к лаконичности и гибкости. Недавно в нем появились combinatorial patterns: and, or, not, а также улучшились positional patterns. Давайте разберём их.

Логические паттерны: and, or, not

Вы можете составлять сложные условия, как в матлогике!

int temperature = 25;
string result = temperature switch
{
    < 0 => "Мороз!",
    >= 0 and < 20 => "Прохладно",
    >= 20 and < 30 => "Комфортно",
    >= 30 or <= -30 => "Экстрим!",
    _ => "Странная температура"
};

Если хочется исключить случаи, пожалуйста:

int score = 80;
string grade = score switch
{
    >= 90 => "Отлично",
    >= 60 and not >= 90 => "Хорошо",
    _ => "Плохо"
};

Деконструкция (Positional Patterns)

Если у вас структура или record, который поддерживает деконструкцию, C# позволяет разбивать объект прямо в switch-выражении:

public record Point(int X, int Y);

Point p = new Point(10, 20);
string desc = p switch
{
    (0, 0) => "Начало координат",
    (var x, 0) => $"На оси X, X={x}",
    (0, var y) => $"На оси Y, Y={y}",
    (var x, var y) when x == y => $"На диагонали: {x}",
    _ => $"В точке ({p.X}, {p.Y})"
};
Console.WriteLine(desc); // => В точке (10, 20)

5. Когда и зачем использовать switch-выражения

В современном C# switch-выражения — это не просто модная "фича", а реальный способ избежать бумагомарания, сделать код компактнее, легче тестировать и поддерживать. Это особенно критично при написании парсеров, обработчиков команд, бизнес-логики, конфигурирования правил — везде, где нужно разветвлять исполнение по сложным критериям, в том числе не только по значениям, но и по типам, диапазонам, свойствам, комбинациям.

На собеседованиях

  • Как бы вы обработали разные варианты ответа от пользователя?
  • Как сделать так, чтобы вернуть разное значение функции, зависящее и от типа, и от значения?
  • Как вы будете легко добавлять новые правила без кучи if-else?

Покажите switch-выражение с паттернами! Это сразу продемонстрирует ваше знание новых возможностей языка и хороший стиль кодинга.

Таблица: сравнение switch-оператора и switch-выражения

Характеристика switch statement switch expression
Тип оператор (statement) выражение (expression)
Использование break обязательно не нужен
Может возвращать значение только через переменную да, прямо возвращает значение
Может использовать паттерны частично полностью (type, property, и др.)
Ловушка можно забыть break все пути должны вернуть значение

6. Типичные ошибки и мелкие пакости

  • Начинающие разработчики часто путаются в разнице между switch-оператором ("statement") и switch-выражением ("expression"). Например, забывают, что в switch-выражении не нужны break;, а все ветви обязательно должны возвращать значение.
  • Если забыть ветку _, компилятор подскажет: "а если ничего не подошло?".
  • В switch-выражении нельзя использовать goto (и слава богу!).
  • Если дублируется условие (например, два одинаковых паттерна), компилятор это тоже не пропустит.
  • Внимательно относитесь к типу значения, возвращаемого из switch-выражения: он должен быть совместим с типом переменной, куда вы это всё присваиваете.
2
Задача
C# SELF, 10 уровень, 5 лекция
Недоступна
Простой switch-выражение с паттернами
Простой switch-выражение с паттернами
2
Задача
C# SELF, 10 уровень, 5 лекция
Недоступна
Валидация пароля по длине и символам
Валидация пароля по длине и символам
1
Опрос
Константы и ключевое слово var, 10 уровень, 5 лекция
Недоступен
Константы и ключевое слово var
Константы, структуры, enum и switch
Комментарии (6)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
mr Arkmaster Уровень 11
1 января 2026
Ребят халтура, решение является правильным хотя выдаёт ошибку(я имею в виду что он принимает это решение при этом в выводе только ошибки) // Запрашиваем у пользователя ввод температуры Console.Write("Введите температуру (целое число): "); string input = Console.ReadLine(); int temperature = int.Parse(input); // Применяем паттерны для проверки диапазонов значений string weatherCondition = temperature switch { < 0 : "Очень холодно", >= 0 and <= 15: "Прохладно", >= 16 and <= 25: "Комфортно", >= 26 and <= 35: "Тепло", > 35: "Очень жарко" } // Выводим результат Console.WriteLine($"Температура {temperature}°C: {weatherCondition}");
whynot00 Уровень 1
16 сентября 2025
наконец таки, впервые за весь курс задача (№ 2) заставляет подумать
Александр Уровень 21
21 октября 2025
да, хоть где-то удалось кайфануть
Ra Уровень 35 Student
15 сентября 2025
Как всегда, юзаем Pattern matching до его обьяснения?
Aleksei Perchukov Уровень 66
3 августа 2025
А что за goto?
Ra Уровень 35 Student
15 сентября 2025
Оператор такой. Правилами хорошего кода не рекомендуется, усложняет чтение кода: (если язык не Ассемблер 😂) goto label; // ... label: Console.WriteLine("Here"); Java - зарезервировано слово goto, но не используется. В Java есть отдаленный аналог для break и continue

// Выход из вложенных циклов
outer: for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (i * j > 50) break outer; // выход из обоих циклов
    }
}