通八洲科技

c# 编译器 roslyn 是什么

日期:2025-12-29 00:00 / 作者:星降
Roslyn 是微软开源的可编程 C#/VB.NET 编译器平台,将编译过程拆解为语法分析→语义分析→绑定→IL生成四阶段,暴露强类型API;其核心是不可变SyntaxTree(结构)与需手动引用的Compilation(语义),支持代码分析、修改与生成。

Roslyn 不是传统意义上“黑盒式”的编译器,它是微软开源的、可编程的 C#(和 VB.NET)编译器平台——你可以把它当成一个“带 API 的编译器”,而不是只能敲 dotnet build 的工具。

它把编译过程拆成可观察、可干预的阶段:语法分析 → 语义分析 → 绑定 → IL 生成。每个阶段都暴露了强类型的 API,让你能读取、遍历、修改甚至重新生成代码。


为什么 Roslyn 能解析代码还能改代码?

因为 Roslyn 把源码转成了两棵关键树:SyntaxTree(纯结构,不关心含义)和 Compilation(带类型、符号、引用信息)。前者告诉你“代码长什么样”,后者告诉你“这段代码到底在干啥”。
比如你写 var x = new List();SyntaxTree 只知道这是个变量声明,而 Compilation 能告诉你 List 是来自 System.Collections.Generic,且 var 推导为 List


动态编译字符串代码时最常卡在哪?

不是语法错,而是环境缺失。Roslyn 默认不带任何框架引用,哪怕只写 Console.WriteLine,也得手动加 System.Console 对应的元数据引用。

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

string code = @"using System; class A { static void Main() => Console.WriteLine(1); }"; SyntaxTree tree = CSharpSyntaxTree.ParseText(code);

// ⚠️ 下面这步极易遗漏 CSharpCompilation compilation = CSharpCompilation.Create("tmp.dll") .AddSyntaxTrees(tree) .AddReferences( MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(Console).Assembly.Location) ) .WithOptions(new CSharpCompilationOptions(OutputKind.ConsoleApplication));

// 编译失败?先看 diagnostics: foreach (Diagnostic d in compilation.GetDiagnostics()) Console.WriteLine(d.ToString());


Roslyn 分析器(Analyzer)和源生成器(Source Generator)有什么区别?

两者都基于 Roslyn API,但生命周期和用途完全不同:


真正难的从来不是“怎么调 API”,而是理解 Roslyn 的两个世界:一个是语法层面的“字面结构”,一个是语义层面的“真实含义”。漏掉一次引用、误用 SyntaxFactory 而没设 Parent、在生成器里试图访问尚未生成的符号——这些坑不会报编译错误,只会让生成结果为空或诊断静默失效。