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. Если вы моделировали отношения “одно из” деревьями наследования или трюками с кортежами, сейчас хорошее время, чтобы прототипировать с настоящим инструментом.