MST

星途 面试题库

面试题:C# 中 Roslyn Analyzer 的基础实现

请简述在 C# 项目中如何创建一个简单的 Roslyn Analyzer,用于检测方法中是否包含特定的字符串。需要说明涉及到的主要类和方法,以及实现的大致步骤。
11.6万 热度难度
编程语言C#

知识考点

AI 面试

面试题答案

一键面试
  1. 主要涉及的类和方法
    • Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer:这是所有分析器的基类,自定义分析器需要继承此类。
    • Microsoft.CodeAnalysis.Diagnostic:用于表示诊断信息,分析器发现问题时会创建该对象。
    • Microsoft.CodeAnalysis.DiagnosticDescriptor:用于描述诊断的元数据,如 ID、标题、描述等。
    • Microsoft.CodeAnalysis.SyntaxNodeAnalysisContext:在分析语法节点时提供上下文信息,包含语法节点、语义模型等。
  2. 实现大致步骤
    • 创建项目
      • 在 Visual Studio 中创建一个新的类库项目,目标框架为.NET Standard 2.0 或更高版本。
      • 安装 NuGet 包 Microsoft.CodeAnalysis.Analyzers,此包提供了创建 Roslyn 分析器所需的基础类型。
    • 定义诊断描述符: 在分析器类中定义一个 DiagnosticDescriptor 字段,用于描述发现问题时生成的诊断信息。例如:
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
    "MyAnalyzer001",
    "Method contains specific string",
    "Method '{0}' contains the specific string '{1}'",
    "Naming",
    DiagnosticSeverity.Warning,
    isEnabledByDefault: true);
  • 实现分析器逻辑: 继承 DiagnosticAnalyzer 类,重写 Initialize 方法。在 Initialize 方法中注册语法节点分析动作。例如,假设要分析方法体中的字符串,注册对 MethodDeclarationSyntax 节点的分析:
public override void Initialize(AnalysisContext context)
{
    context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
    context.EnableConcurrentExecution();
    context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.MethodDeclaration);
}

然后实现 AnalyzeMethod 方法,在此方法中获取方法体,遍历其中的字符串字面量,检查是否包含特定字符串:

private void AnalyzeMethod(SyntaxNodeAnalysisContext context)
{
    var methodDeclaration = (MethodDeclarationSyntax)context.Node;
    var methodBody = methodDeclaration.Body;
    if (methodBody!= null)
    {
        var specificString = "yourSpecificString";
        foreach (var token in methodBody.DescendantTokens())
        {
            if (token.Kind() == SyntaxKind.StringLiteralToken && token.Text.Contains(specificString))
            {
                var diagnostic = Diagnostic.Create(Rule, token.GetLocation(), methodDeclaration.Identifier.Text, specificString);
                context.ReportDiagnostic(diagnostic);
            }
        }
    }
}
  • 打包和使用: 将分析器项目生成的 DLL 打包为 NuGet 包。在需要使用该分析器的 C# 项目中安装此 NuGet 包,编译项目时,分析器就会运行并检测方法中是否包含特定字符串,发现问题会在 Visual Studio 的错误列表中显示诊断信息。