C# 8 → 12
Тема дорожной карты · .NET / C# Developer
C# за последние пять лет прошёл через несколько крупных эволюций: C# 8 (.NET Core 3.x) принёс nullable reference types и async streams, C# 9 (.NET 5) — records и top-level statements, C# 10 (.NET 6) — file-scoped namespaces и global usings, C# 11 (.NET 7) — required members и raw string literals, C# 12 (.NET 8) — primary constructors и collection expressions. Каждая версия добавляет либо синтаксический сахар, либо реальные новые возможности — суммарно язык стал заметно лаконичнее.
Как это работает
Версия C# определяется в .csproj через <LangVersion> либо выводится из target framework: .NET 8 = C# 12 по умолчанию, .NET 6 LTS = C# 10. Компилятор Roslyn реализует все версии, но некоторые фичи требуют рантайма (например, default interface methods C# 8 работают только на .NET Core 3+). Records — это immutable классы с автогенерированными Equals, GetHashCode, ToString и with-выражениями. Pattern matching расширен через switch expressions, property patterns, list patterns (C# 11). Required свойства — это компиляторный аналог обязательных конструкторных параметров без бойлерплейта.
Когда применять
Целитесь в самую свежую LTS-версию .NET (сейчас .NET 8) и используйте все её C#-фичи. Records — для всех value-классов (DTO, value objects). File-scoped namespaces и global usings — стандарт нового кода с C# 10. Primary constructors C# 12 — для коротких сервисных классов с DI-инъекциями. На старых LTS (.NET 6) ограничения переносимы, но не пытайтесь использовать C# 12 фичи на .NET 6 — компилятор разрешит часть синтаксиса, но рантайм-фичи не сработают.
Типичные ошибки
Использование пакетов на C# 12 в библиотеке, ориентированной на .NET Standard 2.0 — некоторые синтаксические фичи требуют рантайм-полифиллов. Игнорирование Nullable контекста при апгрейде версии — компилятор внезапно начинает ругаться. Records без понимания value-equality семантики — приводит к неожиданностям с коллекциями и dictionary-ключами.