Учебные примеры по Roslyn (Microsoft.CodeAnalysis): синтаксические деревья,
семантика, символы, walker'ы/rewriter'ы, workspace, анализаторы, а также
продвинутые приёмы — IOperation, data-flow/CFG, CodeFix, taint-анализ,
архитектурные правила и source generators.
Полноценная серия статей к этим примерам — в docs/roslyn-analyzers/.
Каждый пример — это file-based приложение .NET 10: один .cs-файл, который
запускается командой dotnet run <файл>.cs без отдельного .csproj. Зависимости
от NuGet и свойства сборки задаются прямо в файле директивами #: в начале.
Почему не
.dib? Раньше примеры были ноутбуками.dibдля .NET Interactive / Polyglot Notebooks. Microsoft объявила их deprecation (весна 2026). Проект переведён на file-based apps — поддерживаемый и self-contained способ запускать одиночные.cs-сценарии.
| Компонент | Версия |
|---|---|
| .NET SDK | 10.x (file-based apps — GA с .NET 10) |
Проверка:
dotnet --version # ожидается 10.xНикаких глобальных инструментов (dotnet interactive и т. п.) больше не нужно.
Из корня репозитория:
# Основы dotnet run 01-syntax-tree.cs dotnet run 02-semantic-model.cs dotnet run 03-symbols.cs dotnet run 04-walkers-rewriters.cs dotnet run 05-workspace.cs dotnet run 06-analyzers.cs # Продвинутые примеры (к статьям docs/roslyn-analyzers/) dotnet run 07-ioperation.cs dotnet run 08-dataflow.cs dotnet run 09-codefix.cs dotnet run 10-taint.cs dotnet run 11-architecture.cs dotnet run 12-source-generator.cs
Первый запуск каждого файла скачивает NuGet-пакеты из директив #:package и
собирает приложение — это нормально и происходит один раз (дальше из кеша).
Файл — обычный C# с операторами верхнего уровня. В начале — директивы #::
#:package Microsoft.CodeAnalysis.CSharp@4.* // ссылка на NuGet-пакет (= #r "nuget: …") #:property NoWarn=IL3000 // MSBuild-свойство using Microsoft.CodeAnalysis.CSharp; var tree = CSharpSyntaxTree.ParseText("class A {}"); Console.WriteLine(tree.GetRoot().Kind()); // Объявления типов идут ПОСЛЕ операторов верхнего уровня: static class Helper { /* ... */ }
| Директива | Назначение | Аналог в .dib |
|---|---|---|
#:package Id@Version |
NuGet-зависимость | #r "nuget: Id, Version" |
#:property Name=Value |
свойство MSBuild (напр. NoWarn, TargetFramework) |
— |
#:project ../Path.csproj |
ссылка на проект | #r "путь.dll" |
Важно: в одном файле все операторы верхнего уровня идут до любых объявлений типов. Поэтому walker'ы, rewriter'ы и анализаторы определены в конце своих файлов.
Если файл «дорос» до полноценного проекта:
dotnet project convert 05-workspace.cs
Команда создаст .csproj с тем же содержимым и перенесёт директивы #: в него.
| Файл | Тема |
|---|---|
| 01-syntax-tree.cs | Парсинг, обход SyntaxTree, SyntaxNode / SyntaxToken / SyntaxTrivia, SyntaxKind, span |
| 02-semantic-model.cs | CSharpCompilation, SemanticModel, типы и символы выражений, диагностики |
| 03-symbols.cs | Иерархия ISymbol, GetDeclaredSymbol, навигация по namespace, SpecialType |
| 04-walkers-rewriters.cs | CSharpSyntaxWalker, CSharpSyntaxRewriter, трансформация кода |
| 05-workspace.cs | MSBuildWorkspace, открытие проекта, анализ всех классов и методов |
| 06-analyzers.cs | DiagnosticAnalyzer, запуск анализаторов in-process |
| 07-ioperation.cs | IOperation-дерево, GetOperation, OperationKind, формы присваивания |
| 08-dataflow.cs | AnalyzeDataFlow, ControlFlowGraph, «можно ли сделать const», неиспользуемые локали |
| 09-codefix.cs | CodeFixProvider, применённый in-process через Document/Workspace (до→после) |
| 10-taint.cs | Наивный intraprocedural taint-анализ (source→sink) на IOperation |
| 11-architecture.cs | Анализаторы слоёв (Domain↛Infrastructure) и конвенций именования |
| 12-source-generator.cs | IIncrementalGenerator + CSharpGeneratorDriver, генерация ToString() |
Рекомендуемый порядок — по номерам в имени файла. Каждый файл самодостаточен: в отличие от ноутбуков, состояние между файлами не разделяется.
Примеры 01–06 — основы Roslyn; 07–12 — продвинутые приёмы, идущие в паре с серией статей в docs/roslyn-analyzers/.
-
Утилиты
NetAnalyticsLab.Helpersвлиты в приложения. Бывшая библиотека (SyntaxExtensions.PrintTree,CompilationExtensions.CreateInMemory) удалена; её код перенесён в конец соответствующих.cs-файлов (раздел «влитые утилиты»). -
05-workspace.csсоздаёт временный demo-проект. Отдельного.csprojв репозитории больше нет, поэтому пример сам генерирует небольшой проект во временной папке, открывает его черезMSBuildWorkspaceи удаляет в конце — оставаясь полностью self-contained. -
MSBuildWorkspaceи MSBuild.MSBuildWorkspaceтребуетMSBuildLocator.RegisterDefaults()(вызывается в05-workspace.cs). MSBuild затягивается транзитивно; так как#:packageне поддерживаетExcludeAssets/PrivateAssets, в файле выставлено#:property DisableMSBuildAssemblyCopyCheck=true. -
#:property NoWarn=…в некоторых файлах глушит шумные предупреждения (IL3000— single-file анализAssembly.Location;RS1036/RS1041/RS2008— правила авторинга анализаторов), не влияющие на учебные сценарии.
- JetBrains Rider / Visual Studio / VS Code открывают
.cs-файлы как обычный C# — с полноценным IntelliSense, в отличие от.dib. Запуск — из терминала командойdotnet run <файл>.csили через конфигурацию запуска IDE.
| Симптом | Что проверить |
|---|---|
dotnet run file.cs не распознаёт файл |
Нужен .NET SDK 10.x (dotnet --version) |
| Долгий первый запуск | NuGet restore по директивам #:package — нормально один раз |
MSBuildWorkspace падает |
Вызван ли MSBuildLocator.RegisterDefaults() до использования workspace |
| Ошибка «top-level statements must precede type declarations» | Объявления классов должны идти в конце файла |