Source generators

Тема дорожной карты · .NET / C# Developer

Source generators — компиляторная фича C# 9, позволяющая генерировать дополнительный C#-код во время компиляции на основе анализа уже написанного. По сути это плагины к Roslyn-компилятору: они получают Compilation объект, инспектируют существующие типы и атрибуты, генерируют новые исходники, которые включаются в ту же сборку. Преимущество перед reflection — генерация работает один раз при компиляции, без рантайм-стоимости.

Как это работает

Генератор — это класс с интерфейсом IIncrementalGenerator, аннотированный [Generator]. Регистрирует pipeline через Initialize(context): фильтр синтаксических узлов или семантических символов → трансформация в модель → генерация исходников. Incremental версия (рекомендуется) кэширует промежуточные результаты, поэтому повторная компиляция трогает только изменившиеся файлы. Сгенерированные файлы видны в IDE (под Properties → Dependencies → Analyzers), их можно ставить точки останова, дебажить. Самые известные генераторы — System.Text.Json source-generated JsonSerializerContext, Regex source generator (C# 11), LoggerMessageGenerator, MediatR analyzer.

Когда применять

Используйте source generators, когда у вас есть повторяющийся шаблонный код, который можно вывести из метаданных: маппинг DTO ↔ entity, регистрация в DI по конвенции, обёртки REST-клиента из интерфейса. AOT-сценарии (Native AOT, Blazor WASM) требуют source generators вместо reflection — она там запрещена или медленнее. Не применяйте для одноразовых задач — стоимость поддержки генератора выше стоимости копипаста.

Типичные ошибки

Использование ISourceGenerator (legacy API) вместо IIncrementalGenerator — без incremental кэширования компиляция деградирует на больших проектах в десятки раз. Генерация кода в init-фазе вместо output-фазы pipeline — потеря всех инкрементальных оптимизаций. Зависимость от пакетов, которые сами не AOT-совместимы — генератор не работает в Native AOT сборках. Отсутствие тестов для генератора — изменения ломают пользователей незаметно, используйте Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing для unit-проверок.

Связанные понятия

Полезные ресурсы