面试题答案
一键面试- 主要涉及的类和方法:
- Microsoft.CodeAnalysis.Diagnostics.DiagnosticAnalyzer:这是所有分析器的基类,自定义分析器需要继承此类。
- Microsoft.CodeAnalysis.Diagnostic:用于表示诊断信息,分析器发现问题时会创建该对象。
- Microsoft.CodeAnalysis.DiagnosticDescriptor:用于描述诊断的元数据,如 ID、标题、描述等。
- Microsoft.CodeAnalysis.SyntaxNodeAnalysisContext:在分析语法节点时提供上下文信息,包含语法节点、语义模型等。
- 实现大致步骤:
- 创建项目:
- 在 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 的错误列表中显示诊断信息。