【进阶编程】Roslyn 解析 C# 语法树(Syntax Tree)的节点详解

Roslyn 解析 C# 语法树(Syntax Tree)的节点详解

Roslyn 解析 C# 代码后会生成一棵 语法树(Syntax Tree),其中每个代码元素(类、方法、变量等)都是一个 语法节点(SyntaxNode)

在 Roslyn 中,语法树的核心结构包括:

  • SyntaxTree(语法树)
  • SyntaxNode(语法节点)
  • SyntaxToken(语法标记,如关键字、标点符号)
  • SyntaxTrivia(额外信息,如空格、注释)

1. 语法树的基本结构

代码示例

using System;
class HelloWorld
{
    static void Main()
    {
        Console.WriteLine("Hello, Roslyn!");
    }
}

Roslyn 会将这段代码解析为以下层级结构:

CompilationUnitSyntax
 ├── UsingDirectiveSyntax (using System;)
 ├── ClassDeclarationSyntax (class HelloWorld)
 │    ├── MethodDeclarationSyntax (static void Main())
 │         ├── ExpressionStatementSyntax (Console.WriteLine("Hello, Roslyn!");)
 │              ├── InvocationExpressionSyntax
 │                   ├── MemberAccessExpressionSyntax (Console.WriteLine)
 │                   ├── ArgumentListSyntax ("Hello, Roslyn!")

2. 主要 SyntaxNode 类型

每个 C# 代码结构都对应一个 SyntaxNode,以下是常见的 Roslyn 语法节点:

(1)根节点(CompilationUnitSyntax)

作用:表示整个 C# 代码文件的最顶层节点。

CompilationUnitSyntax root = syntaxTree.GetRoot();

(2)命名空间 & Using 指令

语法节点 作用
UsingDirectiveSyntax using System; 这样的 using 语句
NamespaceDeclarationSyntax namespace MyNamespace { ... }

示例

using Microsoft.CodeAnalysis.CSharp;

string code = "using System; namespace Demo { class A {} }";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();

// 获取 using 指令
var usingDirective = root.DescendantNodes().OfType<UsingDirectiveSyntax>().First();
Console.WriteLine(usingDirective.Name); // 输出:System

// 获取命名空间
var namespaceDecl = root.DescendantNodes().OfType<NamespaceDeclarationSyntax>().First();
Console.WriteLine(namespaceDecl.Name); // 输出:Demo

(3)类 & 结构体

语法节点 作用
ClassDeclarationSyntax 类定义,如 class A {}
StructDeclarationSyntax 结构体定义,如 struct S {}

示例

string code = "class A { }";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
var classNode = root.DescendantNodes().OfType<ClassDeclarationSyntax>().First();
Console.WriteLine(classNode.Identifier); // 输出:A

(4)方法

语法节点 作用
MethodDeclarationSyntax 方法定义,如 void Foo() { }

示例

string code = "class A { void Foo() { } }";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
var methodNode = root.DescendantNodes().OfType<MethodDeclarationSyntax>().First();
Console.WriteLine(methodNode.Identifier); // 输出:Foo

(5)变量 & 变量声明

语法节点 作用
VariableDeclarationSyntax 变量声明,如 int x = 10;
VariableDeclaratorSyntax 变量定义,如 x = 10

示例

string code = "class A { int x = 10; }";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
var variableNode = root.DescendantNodes().OfType<VariableDeclaratorSyntax>().First();
Console.WriteLine(variableNode.Identifier); // 输出:x

(6)表达式

语法节点 作用
LiteralExpressionSyntax 字面量,如 "Hello"10
BinaryExpressionSyntax 二元表达式,如 a + b
InvocationExpressionSyntax 方法调用,如 Console.WriteLine()
AssignmentExpressionSyntax 赋值语句,如 x = 5;

示例:解析 Console.WriteLine("Hello")

string code = "class A { void Foo() { Console.WriteLine(\"Hello\"); } }";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
var invocationNode = root.DescendantNodes().OfType<InvocationExpressionSyntax>().First();
Console.WriteLine(invocationNode.Expression); // 输出:Console.WriteLine

(7)控制流

语法节点 作用
IfStatementSyntax if 语句
ForStatementSyntax for 语句
WhileStatementSyntax while 语句
SwitchStatementSyntax switch 语句

示例:解析 if 语句

string code = "class A { void Foo() { if (true) { Console.WriteLine(\"Yes\"); } } }";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
var ifNode = root.DescendantNodes().OfType<IfStatementSyntax>().First();
Console.WriteLine(ifNode.Condition); // 输出:true

(8)语法标记 & 附加信息

语法节点 作用
SyntaxToken 关键字、标点符号,如 public;
SyntaxTrivia 注释、空格等,如 // 注释

示例:获取注释

string code = "// This is a comment\nclass A { }";
var tree = CSharpSyntaxTree.ParseText(code);
var root = tree.GetRoot();
var comment = root.DescendantTrivia().FirstOrDefault();
Console.WriteLine(comment.ToString()); // 输出:// This is a comment

3. 总结

语法节点 示例
CompilationUnitSyntax 整个 C# 代码文件
UsingDirectiveSyntax using System;
NamespaceDeclarationSyntax namespace MyNamespace {}
ClassDeclarationSyntax class A {}
MethodDeclarationSyntax void Foo() {}
VariableDeclarationSyntax int x = 10;
InvocationExpressionSyntax Console.WriteLine("Hello");
IfStatementSyntax if (true) {}

Roslyn 语法树的优势
解析 C# 代码(可用于代码分析、代码重写)
静态代码检查(如代码风格分析、代码补全)
代码转换(如自动修正、代码重构)

你可能感兴趣的:(技术,.net,进阶编程,c#)