AiKraft
Релиз модели25 октября 2026 г., 21:45 МСК🤖 Auto

C# 15: Union-типы, закрытые иерархии и именованные break

Microsoft представила ключевые нововведения C# 15: union-типы для безопасного объединения разнородных данных, модификатор closed для контроля наследования и именованные break/continue.

Баннер новости 10487

Union-типы: отказ от object и наследования

Самое значимое изменение в C# 15 — введение union-типов. Это структура, позволяющая объединять несколько типов без использования наследования или интерфейсов. Компилятор знает полный список типов внутри union, что делает код безопаснее и избавляет от необходимости обрабатывать default в switch-выражениях.

Ранее для обработки разнородных ответов API приходилось создавать абстрактные базовые классы или использовать object с последующим приведением типов, что часто приводило к ошибкам runtime. Union-типы решают эту проблему на этапе компиляции.

Сравнение подходов: до и после

Ниже приведено сравнение реализации обработки результатов API в старом и новом стиле:

Характеристика Старый подход (Наследование) Новый подход (Union-типы)
Объявление типа Абстрактный класс ApiResult и наследники Union: public union ApiResult(Success, ValidationError)
Безопасность Риск пропуска новых наследников в default Компилятор требует обработки всех типов
Сложность кода Высокая (иерархия классов) Низкая (плоская структура)
Методы внутри Требуют виртуальных вызовов Можно определить методы прямо в union

Закрытые иерархии (Closed Hierarchies)

Параллельно с union-типами вводится модификатор closed. Он запрещает наследование от класса за пределами сборки, где он объявлен. Это гибрид internal и sealed, полезный для библиотек, где нужно ограничить расширение функционала внешними разработчиками.

  • Классы с closed всегда абстрактны.
  • Позволяет использовать exhaustive switch без ветки default.
  • Применимо только к классам и record class (не к структурам и интерфейсам).

Именованные break и continue

Мелкое, но важное улучшение синтаксиса. Теперь можно прерывать или пропускать итерации внешних циклов, помечая их метками:

outer: foreach (var item in workList) {
    switch (item.Type) {
        case WorkItemType.StopAll:
            break outer; // Выход из внешнего цикла
    }
}

Это устраняет необходимость во временных флагах (например, bool stopProcessing) и делает код чище. Поддерживаются конструкции: for, foreach, while, do, switch.

Индексаторы расширений

Появилась возможность определять индексаторы расширения для коллекций. Это позволяет использовать синтаксис collection[index] для типов, реализующих IReadOnlyList или Range, без необходимости писать вспомогательные методы вроде Slice.

Источник: Habr ↗