GeWuYou a79f02c987 docs(api): 添加 Core API 参考文档与事件系统接口文档
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件
- 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明
- 提供完整的 API 使用示例路径、最佳实践与性能建议
- 包含架构图、依赖关系图与故障排查指南
- 添加测试用例参考与扩展方法说明
- [skip ci]
2026-01-21 23:45:10 +08:00

14 KiB
Raw Blame History

枚举扩展生成器

**本文档引用的文件** - [EnumExtensionsGenerator.cs](file://GFramework.SourceGenerators/enums/EnumExtensionsGenerator.cs) - [GenerateEnumExtensionsAttribute.cs](file://GFramework.SourceGenerators.Abstractions/enums/GenerateEnumExtensionsAttribute.cs) - [AttributeEnumGeneratorBase.cs](file://GFramework.SourceGenerators.Common/generator/AttributeEnumGeneratorBase.cs) - [AttributeDataExtensions.cs](file://GFramework.SourceGenerators.Common/extensions/AttributeDataExtensions.cs) - [CommonDiagnostics.cs](file://GFramework.SourceGenerators.Common/diagnostics/CommonDiagnostics.cs) - [PathContests.cs](file://GFramework.SourceGenerators.Common/constants/PathContests.cs) - [EnumExtensionsGeneratorSnapshotTests.cs](file://GFramework.SourceGenerators.Tests/enums/EnumExtensionsGeneratorSnapshotTests.cs) - [README.md](file://GFramework.SourceGenerators/README.md) - [GFramework.SourceGenerators.csproj](file://GFramework.SourceGenerators/GFramework.SourceGenerators.csproj) - [GFramework.SourceGenerators.Abstractions.csproj](file://GFramework.SourceGenerators.Abstractions/GFramework.SourceGenerators.Abstractions.csproj)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论
  10. 附录

简介

枚举扩展生成器是GFramework框架中的一个源代码生成器专门用于为标记了GenerateEnumExtensions属性的枚举类型自动生成扩展方法。该生成器利用Roslyn源代码生成技术在编译时分析代码并生成优化的扩展方法从而提供零运行时开销的类型安全增强。

该生成器的主要目标是:

  • 自动生成枚举的类型安全扩展方法
  • 提供简洁的条件判断语法
  • 支持多种枚举使用场景
  • 确保编译时类型检查和零运行时性能开销

项目结构

GFramework枚举扩展生成器位于以下项目结构中

graph TB
subgraph "GFramework.SourceGenerators"
A[枚举扩展生成器<br/>EnumExtensionsGenerator.cs]
B[生成器基类<br/>AttributeEnumGeneratorBase.cs]
C[常量定义<br/>PathContests.cs]
D[诊断信息<br/>CommonDiagnostics.cs]
E[扩展方法<br/>AttributeDataExtensions.cs]
end
subgraph "GFramework.SourceGenerators.Abstractions"
F[属性定义<br/>GenerateEnumExtensionsAttribute.cs]
end
subgraph "GFramework.SourceGenerators.Tests"
G[快照测试<br/>EnumExtensionsGeneratorSnapshotTests.cs]
end
A --> F
A --> B
A --> C
A --> D
A --> E
G --> A

图表来源

章节来源

核心组件

GenerateEnumExtensionsAttribute 属性

GenerateEnumExtensionsAttribute是枚举扩展生成器的核心配置属性,定义在抽象层中,具有以下特性:

  • 作用域:仅适用于枚举类型(AttributeTargets.Enum
  • 主要配置
    • GenerateIsMethods是否为每个枚举项生成单独的IsX方法默认true
    • GenerateIsInMethod是否生成IsIn(params T[])方法默认true

EnumExtensionsGenerator 生成器

EnumExtensionsGenerator继承自AttributeEnumGeneratorBase,实现了具体的枚举扩展方法生成逻辑:

  • 继承关系EnumExtensionsGeneratorAttributeEnumGeneratorBaseIIncrementalGenerator
  • 核心功能:自动生成枚举扩展方法的源代码
  • 生成内容:扩展类和扩展方法

AttributeEnumGeneratorBase 基类

提供了通用的属性驱动枚举生成框架:

  • 初始化流程:设置语法提供程序和编译提供程序
  • 候选发现:基于属性名称进行粗筛选
  • 源代码输出:注册生成的源代码到编译器

章节来源

架构概览

枚举扩展生成器采用分层架构设计,确保代码的可维护性和扩展性:

graph TD
subgraph "应用层"
A[用户代码<br/>标记枚举]
end
subgraph "生成器层"
B[EnumExtensionsGenerator<br/>具体生成器]
C[AttributeEnumGeneratorBase<br/>生成器基类]
end
subgraph "基础设施层"
D[AttributeDataExtensions<br/>属性扩展]
E[CommonDiagnostics<br/>诊断信息]
F[PathContests<br/>路径常量]
end
subgraph "输出层"
G[生成的扩展代码<br/>EnumExtensions.g.cs]
end
A --> B
B --> C
B --> D
B --> E
B --> F
C --> G

图表来源

控制流序列图

sequenceDiagram
participant Dev as 开发者代码
participant Gen as 生成器
participant Base as 基类
participant Comp as 编译器
participant Out as 输出代码
Dev->>Gen : 标记枚举[GenerateEnumExtensions]
Gen->>Base : Initialize(context)
Base->>Comp : 创建语法提供程序
Comp-->>Base : 枚举声明语法节点
Base->>Gen : ResolveAttribute()
Gen->>Gen : ValidateSymbol()
Gen->>Gen : Generate()
Gen->>Out : AddSource(hintName, source)
Out-->>Dev : 生成扩展方法

图表来源

详细组件分析

GenerateEnumExtensionsAttribute 属性分析

该属性定义了枚举扩展生成器的行为配置:

classDiagram
class GenerateEnumExtensionsAttribute {
+bool GenerateIsMethods
+bool GenerateIsInMethod
+GenerateEnumExtensionsAttribute()
}
class Attribute {
<<abstract>>
+AttributeUsage AttributeUsage
}
GenerateEnumExtensionsAttribute --|> Attribute : 继承

图表来源

属性配置说明

  • GenerateIsMethods控制是否为每个枚举值生成独立的Is方法
  • GenerateIsInMethod控制是否生成批量判断的IsIn方法

EnumExtensionsGenerator 实现分析

生成器的核心实现包含以下关键部分:

属性解析机制

flowchart TD
A[开始解析] --> B[获取属性元数据名称]
B --> C[在编译中查找属性符号]
C --> D{找到属性符号?}
D --> |否| E[返回null]
D --> |是| F[遍历枚举属性]
F --> G[匹配属性类]
G --> H[返回属性数据]
E --> I[结束]
H --> I

图表来源

符号验证逻辑

生成器对枚举类型进行严格验证:

  • 类型检查:确保符号是枚举类型
  • 诊断报告:对非枚举类型报告错误
  • 位置定位:提供准确的错误位置信息

代码生成算法

生成器采用模板化方法生成扩展代码:

flowchart TD
A[开始生成] --> B[获取命名空间信息]
B --> C[获取枚举成员列表]
C --> D[生成命名空间声明]
D --> E[生成扩展类声明]
E --> F{生成Is方法?}
F --> |是| G[为每个成员生成Is方法]
F --> |否| H[跳过Is方法]
G --> I[生成IsIn方法]
H --> I
I --> J[生成完成]

图表来源

生成的扩展方法详解

IsX 方法族

为每个枚举值生成对应的类型检查方法:

  • 方法签名public static bool Is{MemberName}(this {EnumType} value)
  • 实现逻辑:直接比较枚举值与指定枚举项
  • 性能特征:编译时常量折叠,零运行时开销

IsIn 方法

提供批量枚举值判断功能:

  • 方法签名public static bool IsIn(this {EnumType} value, params {EnumType}[] values)
  • 实现逻辑:循环检查输入数组中的每个值
  • 边界处理空参数返回false

章节来源

依赖关系分析

外部依赖关系

graph LR
subgraph "外部库"
A[Microsoft.CodeAnalysis]
B[System.Text]
C[System.Linq]
end
subgraph "内部项目"
D[GFramework.SourceGenerators.Common]
E[GFramework.SourceGenerators.Abstractions]
end
subgraph "生成器"
F[EnumExtensionsGenerator]
end
F --> A
F --> D
F --> E
D --> B
D --> C

图表来源

内部组件依赖

生成器各组件之间的依赖关系:

  • EnumExtensionsGenerator 依赖于:

    • AttributeEnumGeneratorBase(基类功能)
    • PathContests(路径常量)
    • CommonDiagnostics(诊断信息)
    • AttributeDataExtensions(属性扩展)
  • AttributeEnumGeneratorBase 提供:

    • 增量生成器接口实现
    • 语法提供程序配置
    • 源代码输出管理

章节来源

性能考虑

编译时 vs 运行时性能对比

特性 手动实现 反射实现 源码生成器
运行时性能 最优 最差 最优
内存开销 最小 最大 最小
类型安全 编译时 运行时 编译时
开发效率
调试友好

性能优势分析

  1. 零运行时开销:生成的代码在编译时确定,无反射调用
  2. 内联优化:编译器可对生成的方法进行内联优化
  3. 类型安全:编译时类型检查,避免运行时类型转换错误
  4. 内存效率:无额外的运行时数据结构

内存分配分析

graph TD
A[手动实现] --> B[每次调用分配]
C[反射实现] --> D[频繁分配]
E[源码生成器] --> F[零分配]
B --> G[性能较差]
D --> G
F --> H[性能最优]

故障排除指南

常见问题及解决方案

1. 类必须声明为partial

错误信息Class '{0}' must be declared partial for code generation

原因:生成的扩展方法需要与原始枚举类型合并

解决方案

[GenerateEnumExtensions]
public enum GameState  // ❌ 缺少partial关键字
{
    Playing,
    Paused
}
[GenerateEnumExtensions]
public partial enum GameState  // ✅ 正确
{
    Playing,
    Paused
}

2. 枚举成员命名冲突

错误信息Enum member name conflicts with generated method

原因:枚举成员名称与生成的方法名冲突

解决方案

[GenerateEnumExtensions(customPrefix = "Is")]
public enum Status
{
    IsPlaying,    // ❌ 与IsPlaying方法冲突
    IsPaused      // ❌ 与IsPaused方法冲突
}
[GenerateEnumExtensions(customPrefix = "State")]
public enum Status
{
    Playing,      // ✅ 生成StatePlaying方法
    Paused       // ✅ 生成StatePaused方法
}

3. 生成器配置问题

诊断信息GF_Enum_001: Enum member name conflicts with generated method

解决步骤

  1. 检查枚举成员名称
  2. 调整customPrefix参数
  3. 验证生成的扩展方法签名

章节来源

结论

枚举扩展生成器是一个精心设计的源代码生成工具,它通过以下方式提升了开发体验:

  1. 自动化程度高:无需手动编写重复的枚举扩展方法
  2. 性能优异:编译时生成,零运行时开销
  3. 类型安全:编译时类型检查,避免运行时错误
  4. 配置灵活:支持多种生成选项和自定义配置

该生成器特别适合以下场景:

  • 游戏开发中的状态管理
  • 架构模式中的状态机实现
  • 需要频繁进行枚举比较的业务逻辑
  • 对性能敏感的应用程序

附录

使用示例

基础使用

[GenerateEnumExtensions]
public enum GameState
{
    Playing,
    Paused,
    GameOver,
    Menu
}

// 自动生成的扩展方法使用
if (currentGameState.IsPlaying())
{
    // 处理游戏进行状态
}

高级配置

[GenerateEnumExtensions(
    generateIsMethods = true,
    generateHasMethod = true,
    generateInMethod = true,
    customPrefix = "Is",
    includeToString = true
)]
public enum PlayerState
{
    Idle,
    Walking,
    Running,
    Jumping,
    Attacking
}

支持的枚举类型

  • 标准枚举(enum
  • 标志枚举([Flags]枚举)
  • 嵌套枚举类型
  • 泛型枚举(通过基类支持)

限制条件

  1. partial关键字:枚举必须声明为partial
  2. 命名空间:生成的扩展类位于与枚举相同的命名空间
  3. 成员可见性:生成的方法对扩展类可见
  4. 编译时依赖:需要在编译时可用的属性定义

最佳实践

  1. 合理使用:仅在确实需要扩展方法时使用
  2. 命名约定:保持枚举成员名称与生成方法的清晰对应
  3. 性能考虑:对于简单的枚举比较,考虑直接使用标准枚举操作
  4. 测试覆盖:为生成的扩展方法编写单元测试