语义模型 API 完整参考
深入理解 Roslyn 的语义模型、符号系统和类型系统
📋 文档信息
文档集: 语义模型 API
文档数量: 9 个
总阅读时间: 约 120 分钟
难度级别: 🟡 中级到 🔴 高级
🎯 概览
语义模型(Semantic Model) 是 Roslyn 的核心概念之一,它提供了代码的语义信息,包括类型、符号、作用域等。与语法树只关注代码结构不同,语义模型关注代码的含义。
语法树 vs 语义模型
关键概念
| 概念 | 说明 | 示例 |
|---|---|---|
| SemanticModel | 提供语义信息的模型 | compilation.GetSemanticModel(tree) |
| ISymbol | 代码元素的语义表示 | 类、方法、属性等 |
| ITypeSymbol | 类型的语义表示 | int, string, MyClass |
| Accessibility | 访问修饰符 | Public, Private, Internal |
| SymbolKind | 符号类型 | NamedType, Method, Property |
📚 文档列表
基础文档
| 文档 | 难度 | 阅读时间 | 说明 |
|---|---|---|---|
| INamedTypeSymbol | 🟡 | 20 分钟 | 命名类型符号(类、结构、接口等) |
| IMethodSymbol | 🟡 | 20 分钟 | 方法符号(包括构造函数、运算符等) |
| IPropertySymbol | 🟡 | 15 分钟 | 属性和索引器符号 |
| IFieldSymbol 和 IParameterSymbol | 🟡 | 15 分钟 | 字段和参数符号 |
高级文档
| 文档 | 难度 | 阅读时间 | 说明 |
|---|---|---|---|
| 特性处理 | 🔴 | 15 分钟 | 如何读取和处理特性 |
| 符号比较和等价性 | 🔴 | 15 分钟 | 符号比较的正确方法 |
| 符号查找和导航 | 🔴 | 20 分钟 | 查找和导航符号的技巧 |
实践文档
| 文档 | 难度 | 阅读时间 | 说明 |
|---|---|---|---|
| 最佳实践 | 🟡 | 20 分钟 | 使用语义模型的最佳实践和反模式 |
🗺️ 学习路径
初学者路径
如果你是第一次接触语义模型 API,建议按以下顺序学习:
- 先阅读 INamedTypeSymbol - 了解类型符号的基础
- 然后阅读 IMethodSymbol - 了解方法符号
- 接着阅读 IPropertySymbol - 了解属性符号
- 最后阅读 IFieldSymbol 和 IParameterSymbol - 了解字段和参数符号
进阶路径
掌握基础后,继续学习高级主题:
实践路径
最后,学习最佳实践:
- 阅读 最佳实践 - 了解推荐做法和常见陷阱
- 参考真实场景 - 查看实际应用示例
- 避免反模式 - 学习应该避免的做法
📊 快速参考
常用符号类型
| 符号类型 | 接口 | 文档 | 用途 |
|---|---|---|---|
| 类、结构、接口 | INamedTypeSymbol | 查看 | 表示命名类型 |
| 方法 | IMethodSymbol | 查看 | 表示方法、构造函数等 |
| 属性 | IPropertySymbol | 查看 | 表示属性和索引器 |
| 字段 | IFieldSymbol | 查看 | 表示字段 |
| 参数 | IParameterSymbol | 查看 | 表示方法参数 |
常用操作
| 操作 | 方法 | 文档 |
|---|---|---|
| 获取类型符号 | semanticModel.GetDeclaredSymbol() | INamedTypeSymbol |
| 获取方法符号 | semanticModel.GetDeclaredSymbol() | IMethodSymbol |
| 读取特性 | symbol.GetAttributes() | 特性处理 |
| 比较符号 | SymbolEqualityComparer.Default.Equals() | 符号比较 |
| 查找符号 | compilation.GetTypeByMetadataName() | 符号查找 |
💡 核心概念速查
SemanticModel 核心方法
csharp
// 获取声明的符号
ISymbol? symbol = semanticModel.GetDeclaredSymbol(syntaxNode);
// 获取类型信息
TypeInfo typeInfo = semanticModel.GetTypeInfo(expression);
// 获取符号信息(用于引用)
SymbolInfo symbolInfo = semanticModel.GetSymbolInfo(expression);
// 查找作用域内的符号
ImmutableArray<ISymbol> symbols = semanticModel.LookupSymbols(position);符号层次结构
🔗 相关资源
相关 API 文档
- 语义模型:成员符号 - 属性、字段、参数的详细文档
- 语义模型:类型和方法 - 类型和方法的基础知识
- 符号系统指南 - 符号系统的入门指南
学习指南
- 学习指南 - 完整的 Roslyn 学习路径
- 语义模型 API 介绍 - 语义模型的基础介绍
实践示例
📝 使用建议
如果你想...
...了解如何获取类型信息 → 阅读 INamedTypeSymbol
...了解如何分析方法 → 阅读 IMethodSymbol
...了解如何处理特性 → 阅读 特性处理
...了解如何比较符号 → 阅读 符号比较和等价性
...了解如何查找符号 → 阅读 符号查找和导航
...了解最佳实践 → 阅读 最佳实践
🚀 快速开始
如果你想快速上手,可以从以下代码开始:
csharp
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
// 1. 获取语义模型
Compilation compilation = /* ... */;
SyntaxTree syntaxTree = /* ... */;
SemanticModel semanticModel = compilation.GetSemanticModel(syntaxTree);
// 2. 获取类符号
var classDecl = syntaxTree.GetRoot()
.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.First();
var classSymbol = semanticModel.GetDeclaredSymbol(classDecl) as INamedTypeSymbol;
// 3. 遍历类的成员
foreach (var member in classSymbol.GetMembers())
{
Console.WriteLine($"{member.Kind}: {member.Name}");
}然后阅读 INamedTypeSymbol 了解更多细节。
最后更新时间:2026-02-05