Skip to content

语义模型 API:命名空间、事件和类型参数符号

📋 文档信息

难度: 🟡 中级
预计阅读时间: 25 分钟
前置知识: 语法树基础、符号系统、语义模型基础
适合人群: 中级开发者


📋 快速导航

章节难度阅读时间链接
概览🟢5 分钟查看
快速开始示例🟢10 分钟查看
API 速查表🟢5 分钟查看
深入学习--查看

深入学习主题

主题难度阅读时间文档链接
命名空间详解🟢30 分钟semantic-model-namespaces.md
事件详解🟢25 分钟semantic-model-events.md
类型参数详解🟡35 分钟semantic-model-type-parameters.md

🎯 概览

本文档介绍三种重要的符号类型:命名空间符号、事件符号和类型参数符号。

INamespaceSymbol(命名空间符号)

  • 表示命名空间,用于组织代码
  • 提供命名空间层次结构和成员访问
  • 用于代码组织分析、命名空间导入优化等

IEventSymbol(事件符号)

  • 表示事件成员
  • 提供事件类型、访问器(add/remove)等信息
  • 用于事件处理分析、观察者模式检测等

ITypeParameterSymbol(类型参数符号)

  • 表示泛型类型参数(如 T
  • 提供类型参数约束、协变/逆变等信息
  • 用于泛型代码分析、约束验证等

🚀 快速开始示例

csharp
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

public class QuickStartExample
{
    public void AnalyzeSymbols()
    {
        string code = @"
            namespace MyApp.Services
            {
                public class EventPublisher<T> where T : class
                {
                    public event EventHandler<T> DataReceived;
                }
            }
        ";
        
        var syntaxTree = CSharpSyntaxTree.ParseText(code);
        var compilation = CSharpCompilation.Create("QuickStart")
            .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location))
            .AddSyntaxTrees(syntaxTree);
        
        var semanticModel = compilation.GetSemanticModel(syntaxTree);
        var root = syntaxTree.GetRoot();
        
        // 1. 分析命名空间
        var namespaceDecl = root.DescendantNodes()
            .OfType<NamespaceDeclarationSyntax>()
            .First();
        var namespaceSymbol = semanticModel.GetDeclaredSymbol(namespaceDecl);
        Console.WriteLine($"命名空间: {namespaceSymbol.ToDisplayString()}");
        
        // 2. 分析事件
        var eventDecl = root.DescendantNodes()
            .OfType<EventFieldDeclarationSyntax>()
            .First();
        var eventSymbol = semanticModel.GetDeclaredSymbol(
            eventDecl.Declaration.Variables[0]) as IEventSymbol;
        Console.WriteLine($"事件: {eventSymbol.Name}");
        Console.WriteLine($"事件类型: {eventSymbol.Type.ToDisplayString()}");
        
        // 3. 分析类型参数
        var classDecl = root.DescendantNodes()
            .OfType<ClassDeclarationSyntax>()
            .First();
        var classSymbol = semanticModel.GetDeclaredSymbol(classDecl);
        foreach (var typeParam in classSymbol.TypeParameters)
        {
            Console.WriteLine($"类型参数: {typeParam.Name}");
            if (typeParam.HasReferenceTypeConstraint)
                Console.WriteLine("  约束: class");
        }
    }
}

📊 API 速查表

命名空间符号常用 API

API说明返回类型示例场景
Name获取命名空间名称stringns.Name获取名称
ContainingNamespace获取父命名空间INamespaceSymbolns.ContainingNamespace遍历层次结构
GetNamespaceMembers()获取子命名空间ImmutableArray<INamespaceSymbol>ns.GetNamespaceMembers()遍历子命名空间
GetTypeMembers()获取类型成员ImmutableArray<INamedTypeSymbol>ns.GetTypeMembers()获取命名空间中的类型
IsGlobalNamespace是否是全局命名空间boolns.IsGlobalNamespace检查全局命名空间

事件符号常用 API

API说明返回类型示例场景
Name获取事件名称stringevt.Name获取名称
Type获取事件类型ITypeSymbolevt.Type获取委托类型
AddMethod获取 add 访问器IMethodSymbolevt.AddMethod分析事件订阅
RemoveMethod获取 remove 访问器IMethodSymbolevt.RemoveMethod分析事件取消订阅
IsOverride是否是重写事件boolevt.IsOverride检查事件重写

类型参数符号常用 API

API说明返回类型示例场景
Name获取类型参数名称stringtp.Name获取名称(如 T)
HasReferenceTypeConstraint是否有 class 约束booltp.HasReferenceTypeConstraint检查引用类型约束
HasValueTypeConstraint是否有 struct 约束booltp.HasValueTypeConstraint检查值类型约束
HasConstructorConstraint是否有 new() 约束booltp.HasConstructorConstraint检查构造函数约束
ConstraintTypes获取类型约束ImmutableArray<ITypeSymbol>tp.ConstraintTypes获取所有类型约束
Variance获取协变/逆变VarianceKindtp.Variance检查协变逆变

🔗 深入学习

1. 命名空间详解

文档: semantic-model-namespaces.md

内容包括

  • INamespaceSymbol 核心属性
  • 命名空间层次结构
  • 命名空间成员访问
  • 全局命名空间处理

2. 事件详解

文档: semantic-model-events.md

内容包括

  • IEventSymbol 核心属性
  • 事件访问器(Add/Remove)
  • 事件类型和委托
  • 事件重写和实现

3. 类型参数详解

文档: semantic-model-type-parameters.md

内容包括

  • ITypeParameterSymbol 核心属性
  • 类型参数约束
  • 泛型方法和类型
  • 协变和逆变

📚 相关资源

API 参考文档

相关文档


📚 下一步

基于 MIT 许可发布