Start Debugging

Union-типы C# 15 здесь: типы-объединения поставляются в .NET 11 Preview 2

C# 15 вводит ключевое слово union для типов-объединений с исчерпывающим сопоставлением с образцом и неявными преобразованиями. Доступно прямо сейчас в .NET 11 Preview 2.

После лет предложений, обходных путей и сторонних библиотек вроде OneOf, C# 15 поставляет ключевое слово union в .NET 11 Preview 2. Это типы-объединения: они компонуют существующие типы в единый закрытый тип с принудительным исчерпывающим сопоставлением с образцом со стороны компилятора. Без базовых классов, без шаблона visitor, без угадываний во время выполнения.

Как выглядят типы-объединения

Объединение объявляет, что значение — ровно один из фиксированного набора типов:

public union Shape(Circle, Rectangle, Triangle);

Shape может содержать Circle, Rectangle или Triangle, и ничего больше. Компилятор генерирует неявные преобразования из каждого типа-кейса, поэтому присваивание прямолинейно:

Shape shape = new Circle(Radius: 5.0);

Без явного приведения, без фабричного метода. Преобразование просто работает.

Исчерпывающее сопоставление с образцом

Реальная отдача приходит при использовании. Выражение switch над объединением должно обрабатывать каждый случай, иначе компилятор выдаёт ошибку:

double Area(Shape shape) => shape switch
{
    Circle c    => Math.PI * c.Radius * c.Radius,
    Rectangle r => r.Width * r.Height,
    Triangle t  => 0.5 * t.Base * t.Height,
};

Ветка default не нужна. Если вы потом добавите Polygon в объединение, каждый switch, который его не обрабатывает, сломается во время компиляции. Это гарантия безопасности, которую иерархии классов и OneOf<T1, T2> не могут обеспечить на уровне языка.

Объединения могут нести логику

Вы не ограничены однострочным объявлением. Объединения поддерживают методы, свойства и дженерики:

public union Result<T>(T, ErrorInfo)
{
    public string Describe() => Value switch
    {
        T val       => $"Success: {val}",
        ErrorInfo e => $"Error {e.Code}: {e.Message}",
    };
}

Свойство Value даёт доступ к нижележащему экземпляру. В сочетании с дженериками это делает шаблоны Result<T> первоклассными без внешних зависимостей.

Чем это отличается от более раннего предложения

В январе 2026 года мы рассказали о предложении дискриминированных объединений, которое определяло члены внутри самого объединения (ближе к перечислениям F# или Rust). Поставленный дизайн C# 15 идёт в другом направлении: типы-объединения компонуют существующие типы, вместо того чтобы объявлять новые инлайн. Это значит, что ваши Circle, Rectangle и Triangle — это обычные классы или record, которые у вас уже есть. Объединение лишь группирует их.

Начало работы

Установите SDK .NET 11 Preview 2, нацельтесь на net11.0 и установите <LangVersion>preview</LangVersion> в файле проекта. Обратите внимание, что в Preview 2 UnionAttribute и интерфейс IUnion<T> ещё не в среде выполнения: вам нужно объявить их в своём проекте. Более поздние превью будут включать их из коробки.

Типы-объединения — крупнейшее расширение системы типов C# со времён ссылочных типов, допускающих null. Если вы моделировали отношения “одно из” деревьями наследования или трюками с кортежами, сейчас хорошее время, чтобы прототипировать с настоящим инструментом.

< Назад