roslyn 分析器是嵌入编译管道的实时诊断组件,区别于传统静态分析(如dll扫描),它在csharpcompilation阶段介入,可访问语法树、语义模型和符号信息,支持精确类型推导而非文本模式匹配。

什么是 Roslyn 分析器,它和传统静态分析有什么区别
Roslyn 分析器不是编译后扫描 DLL 的工具,而是直接嵌入编译管道的实时诊断组件。它在 CSharpCompilation 构建过程中介入,能访问完整的语法树(SyntaxTree)、语义模型(SemanticModel)甚至符号信息(ISymbol)。这意味着你能精确知道某个 var 实际推导出什么类型,而不仅是匹配文本模式。
常见误区是把它当正则替换工具——比如只靠 IdentifierNameSyntax 找变量名,却不检查其 Symbol 是否为 string 类型,结果误报泛型方法参数或字段名。
创建 Analyzer 项目并注册语法/语义分析节点
用 Visual Studio 创建「Analyzer with Code Fix (.NET Standard)」模板最稳妥,它会自动配置 Microsoft.CodeAnalysis.CSharp 和 SDK 风格项目。关键不是写逻辑,而是选对挂载点:
-
SyntaxNodeAction<ifstatementsyntax></ifstatementsyntax>:适合检查 if 条件是否恒真/恒假,但拿不到变量实际值 -
SyntaxNodeAction<binaryexpressionsyntax></binaryexpressionsyntax>:适合检测== null比较,但要注意is null是不同节点类型 -
RegisterSemanticModelAction:必须在这里才能调用semanticModel.GetSymbolInfo(node),否则GetTypeInfo返回空
漏掉 RegisterSemanticModelAction 是新手最常踩的坑——写了语义判断却始终得不到符号,因为没等语义模型就绪就提前执行了。
如何安全地获取类型信息并避免 NullReferenceException
所有从 SemanticModel 获取的信息都可能为 null,尤其在不完整代码(如用户正在输入时)场景下。不能直接链式调用 GetSymbolInfo(...).Symbol.ContainingType。
《PHP设计模式》首先介绍了设计模式,讲述了设计模式的使用及重要性,并且详细说明了应用设计模式的场合。接下来,本书通过代码示例介绍了许多设计模式。最后,本书通过全面深入的案例分析说明了如何使用设计模式来计划新的应用程序,如何采用PHP语言编写这些模式,以及如何使用书中介绍的设计模式修正和重构已有的代码块。作者采用专业的、便于使用的格式来介绍相关的概念,自学成才的编程人员与经过更多正规培训的编程人员
正确做法是逐层判空 + 使用 C# 8+ 的空合并运算符:
var symbol = semanticModel.GetSymbolInfo(expression).Symbol;
if (symbol?.ContainingType?.SpecialType == SpecialType.System_String)
{
// 安全进入
}还要注意:泛型类型(如 List<string></string>)的 SpecialType 是 None,得用 symbol.ContainingType?.IsString() || symbol.Type?.IsString() 辅助判断。
发布与调试:为什么本地测试通过,CI 上却失效
Roslyn 分析器默认只在 IDE 中启用,若要让 dotnet build 或 CI 流水线触发,必须显式引用 NuGet 包并开启分析器:
- 在目标项目中添加
<packagereference include="YourAnalyzer" version="1.0.0" privateassets="all"></packagereference> - 确保
PrivateAssets="all",否则 analyzer dll 不会被 MSBuild 加载 - CI 环境若用
dotnet build -p:AnalysisLevel=latest,需确认你的分析器未被AnalysisMode过滤(如设为Recommended会跳过自定义规则)
最容易被忽略的是:调试时用 F5 启动 VSIX,但发布后用户没装对应版本的 Visual Studio —— 此时分析器仅在 CLI 编译生效,IDE 里不亮灯,让人误以为失效。









