diff --git a/.claude/settings.json b/.claude/settings.json
deleted file mode 100644
index c6802dc..0000000
--- a/.claude/settings.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "enabledPlugins": {
- "oh-my-claudecode@omc": true
- }
-}
diff --git a/.gitignore b/.gitignore
index b27afa0..702e68b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ GFramework.sln.DotSettings.user
# ai
opencode.json
.claude/settings.local.json
+.claude/settings.json
.omc/
docs/.omc/
docs/.vitepress/cache/
\ No newline at end of file
diff --git a/docs/zh-CN/source-generators/enum-generator.md b/docs/zh-CN/source-generators/enum-generator.md
index e5aa9c7..2e3b455 100644
--- a/docs/zh-CN/source-generators/enum-generator.md
+++ b/docs/zh-CN/source-generators/enum-generator.md
@@ -1,172 +1,235 @@
# 枚举扩展生成器
-> GFramework.SourceGenerators 自动生成枚举扩展方法
+> 自动为枚举类型生成扩展方法
## 概述
-枚举扩展生成器为枚举类型自动生成常用的扩展方法,如获取描述、转换为字符串、解析等。这大大简化了枚举的操作。
+枚举扩展生成器为标记了 `[GenerateEnumExtensions]` 属性的枚举自动生成两种扩展方法:
-## 基本用法
+1. **IsX 方法**:为每个枚举值生成判断方法
+2. **IsIn 方法**:判断枚举值是否在指定集合中
-### 标记枚举
+## 基础使用
```csharp
-using GFramework.SourceGenerators.Attributes;
+using GFramework.SourceGenerators.Abstractions.enums;
-[EnumExtensions]
+[GenerateEnumExtensions]
+public enum GameState
+{
+ Normal,
+ Paused,
+ GameOver
+}
+```
+
+## 生成的代码
+
+编译器会自动生成如下扩展方法:
+
+```csharp
+//
+public static class GameStateExtensions
+{
+ // 为每个枚举值生成 IsX 方法
+ public static bool IsNormal(this GameState value)
+ => value == GameState.Normal;
+
+ public static bool IsPaused(this GameState value)
+ => value == GameState.Paused;
+
+ public static bool IsGameOver(this GameState value)
+ => value == GameState.GameOver;
+
+ // 生成 IsIn 方法
+ public static bool IsIn(this GameState value, params GameState[] values)
+ {
+ if (values == null) return false;
+ foreach (var v in values) if (value == v) return true;
+ return false;
+ }
+}
+```
+
+## 使用示例
+
+```csharp
+var state = GameState.Paused;
+
+// 使用 IsX 方法
+if (state.IsPaused())
+{
+ Console.WriteLine("游戏已暂停");
+}
+
+// 使用 IsIn 方法
+if (state.IsIn(GameState.Paused, GameState.GameOver))
+{
+ Console.WriteLine("游戏未在运行中");
+}
+```
+
+## 配置选项
+
+可以通过属性参数控制生成行为:
+
+```csharp
+[GenerateEnumExtensions(
+ GenerateIsMethods = true, // 是否生成 IsX 方法(默认 true)
+ GenerateIsInMethod = true // 是否生成 IsIn 方法(默认 true)
+)]
+public enum GameState
+{
+ Normal,
+ Paused,
+ GameOver
+}
+```
+
+### 只生成 IsX 方法
+
+```csharp
+[GenerateEnumExtensions(GenerateIsInMethod = false)]
+public enum GameState
+{
+ Normal,
+ Paused
+}
+
+// 只生成 IsNormal() 和 IsPaused(),不生成 IsIn()
+```
+
+### 只生成 IsIn 方法
+
+```csharp
+[GenerateEnumExtensions(GenerateIsMethods = false)]
+public enum GameState
+{
+ Normal,
+ Paused
+}
+
+// 只生成 IsIn(),不生成 IsNormal() 和 IsPaused()
+```
+
+## 最佳实践
+
+### 1. 命名约定
+
+生成的方法名基于枚举值名称:
+
+- `Normal` → `IsNormal()`
+- `GameOver` → `IsGameOver()`
+- `HTTP_ERROR` → `IsHTTP_ERROR()`
+
+### 2. 性能考虑
+
+生成的方法是内联的,性能与手写代码相同:
+```csharp
+// 生成的代码
+public static bool IsNormal(this GameState value)
+ => value == GameState.Normal;
+
+// 等价于手写
+if (state == GameState.Normal) { }
+```
+
+### 3. 可读性提升
+
+```csharp
+// 使用生成的方法(推荐)
+if (state.IsPaused())
+{
+ ResumeGame();
+}
+
+// 直接比较(不推荐)
+if (state == GameState.Paused)
+{
+ ResumeGame();
+}
+```
+
+## 实际应用示例
+
+### 游戏状态管理
+
+```csharp
+[GenerateEnumExtensions]
+public enum GameState
+{
+ MainMenu,
+ Playing,
+ Paused,
+ GameOver,
+ Victory
+}
+
+public class GameManager
+{
+ private GameState _currentState = GameState.MainMenu;
+
+ public bool CanProcessInput()
+ {
+ // 使用 IsIn 方法简化多值判断
+ return _currentState.IsIn(GameState.Playing, GameState.MainMenu);
+ }
+
+ public void Update()
+ {
+ // 使用 IsX 方法提高可读性
+ if (_currentState.IsPlaying())
+ {
+ UpdateGameLogic();
+ }
+ else if (_currentState.IsPaused())
+ {
+ UpdatePauseMenu();
+ }
+ }
+}
+```
+
+### 角色状态控制
+
+```csharp
+[GenerateEnumExtensions]
public enum PlayerState
{
Idle,
+ Walking,
Running,
Jumping,
Attacking
}
-```
-### 生成的方法
-
-上面的代码会被转换为:
-
-```csharp
-public static class PlayerStateExtensions
+public class PlayerController
{
- public static string GetDescription(this PlayerState value)
+ private PlayerState _state = PlayerState.Idle;
+
+ public bool CanAttack()
{
- // 返回枚举的描述
+ // 清晰表达可以攻击的状态
+ return _state.IsIn(PlayerState.Idle, PlayerState.Walking, PlayerState.Running);
}
- public static bool HasFlag(this PlayerState value, PlayerState flag)
+ public void HandleInput(string action)
{
- // 检查是否包含标志
- }
-
- public static PlayerState FromString(string value)
- {
- // 从字符串解析枚举
+ if (action == "jump" && !_state.IsJumping())
+ {
+ _state = PlayerState.Jumping;
+ }
}
}
```
-## 常用方法
+## 限制
-### 获取描述
+1. **只支持枚举类型**:不能用于类或结构体
+2. **不支持 Flags 枚举的特殊处理**:对于 `[Flags]` 枚举,生成的方法仍然是简单的相等比较
+3. **不生成其他方法**:只生成 IsX 和 IsIn 方法
-```csharp
-[EnumExtensions]
-public enum ItemQuality
-{
- [Description("普通")]
- Common,
-
- [Description("稀有")]
- Rare,
-
- [Description("史诗")]
- Epic
-}
-
-public void PrintQuality(ItemQuality quality)
-{
- // 获取描述文本
- Console.WriteLine(quality.GetDescription());
- // 输出: "普通" / "稀有" / "史诗"
-}
-```
-
-### 安全解析
-
-```csharp
-public void ParseState(string input)
-{
- // 安全地解析字符串为枚举
- if (PlayerState.Running.TryParse(input, out var state))
- {
- Console.WriteLine($"状态: {state}");
- }
-}
-```
-
-### 获取所有值
-
-```csharp
-public void ListAllStates()
-{
- // 获取所有枚举值
- foreach (var state in PlayerState.GetAllValues())
- {
- Console.WriteLine(state);
- }
-}
-```
-
-## 标志枚举
-
-对于使用 `[Flags]` 特性的枚举:
-
-```csharp
-[EnumExtensions]
-[Flags]
-public enum PlayerPermissions
-{
- None = 0,
- Read = 1,
- Write = 2,
- Execute = 4,
- All = Read | Write | Execute
-}
-
-public void CheckPermissions()
-{
- var permissions = PlayerPermissions.Read | PlayerPermissions.Write;
-
- // 检查是否包含特定权限
- if (permissions.HasFlag(PlayerPermissions.Write))
- {
- Console.WriteLine("有写入权限");
- }
-
- // 获取所有设置的标志
- foreach (var flag in permissions.GetFlags())
- {
- Console.WriteLine($"权限: {flag}");
- }
-}
-```
-
-## 自定义行为
-
-### 忽略某些值
-
-```csharp
-[EnumExtensions(IgnoreValues = new[] { ItemQuality.Undefined })]
-public enum ItemQuality
-{
- Undefined,
- Common,
- Rare,
- Epic
-}
-
-// GetAllValues() 不会返回 Undefined
-```
-
-### 自定义转换
-
-```csharp
-[EnumExtensions(CaseSensitive = false)]
-public enum Difficulty
-{
- Easy,
- Medium,
- Hard
-}
-
-// FromString("EASY") 也能正确解析
-```
-
----
-
-**相关文档**:
+## 相关文档
- [Source Generators 概述](./index)
- [日志生成器](./logging-generator)
diff --git a/docs/zh-CN/source-generators/index.md b/docs/zh-CN/source-generators/index.md
index 36df3c1..c404cdb 100644
--- a/docs/zh-CN/source-generators/index.md
+++ b/docs/zh-CN/source-generators/index.md
@@ -107,46 +107,41 @@ public partial class PlayerController
```csharp
//
-using Microsoft.Extensions.Logging;
-
-namespace YourNamespace
+public partial class PlayerController
{
- public partial class PlayerController
- {
- private static readonly ILogger Logger =
- LoggerFactory.Create(builder => builder.AddConsole()).CreateLogger();
- }
+ private static readonly ILogger Logger =
+ LoggerFactoryResolver.Provider.CreateLogger("YourNamespace.PlayerController");
}
```
+**注意**:生成器只生成 ILogger 字段,不生成日志方法。日志方法(Info、Debug、Error 等)来自 ILogger 接口本身。
+
### 高级配置
```csharp
[Log(
- fieldName = "CustomLogger", // 自定义字段名
- accessModifier = AccessModifier.Public, // 访问修饰符
- isStatic = false, // 是否为静态字段
- loggerName = "Custom.PlayerLogger", // 自定义日志器名称
- includeLoggerInterface = true // 是否包含 ILogger 接口
+ Name = "Custom.PlayerLogger", // 自定义日志分类名称
+ FieldName = "CustomLogger", // 自定义字段名
+ IsStatic = false, // 是否为静态字段
+ AccessModifier = "public" // 访问修饰符
)]
public partial class CustomLoggerExample
{
public void LogSomething()
{
- CustomLogger.LogInformation("Custom logger message");
+ CustomLogger.Info("Custom logger message");
}
}
```
### 配置选项说明
-| 参数 | 类型 | 默认值 | 说明 |
-|--------------------------|----------------|----------|---------------------|
-| `fieldName` | string | "Logger" | 生成的日志字段名称 |
-| `accessModifier` | AccessModifier | Private | 字段访问修饰符 |
-| `isStatic` | bool | true | 是否生成静态字段 |
-| `loggerName` | string | null | 自定义日志器名称,null 时使用类名 |
-| `includeLoggerInterface` | bool | false | 是否包含 ILogger 接口实现 |
+| 参数 | 类型 | 默认值 | 说明 |
+|----------------|---------|-----------|---------------------------------|
+| Name | string? | null | 日志分类名称(默认使用类名) |
+| FieldName | string | "Logger" | 生成的字段名称 |
+| IsStatic | bool | true | 是否生成静态字段 |
+| AccessModifier | string | "private" | 访问修饰符(private/protected/public) |
### 静态类支持
@@ -162,21 +157,6 @@ public static partial class MathHelper
}
```
-### 日志级别控制
-
-```csharp
-[Log(minLevel = LogLevel.Warning)]
-public partial class WarningOnlyLogger
-{
- public void ProcessData()
- {
- Logger.Debug("This won't be logged"); // 低于最小级别,被过滤
- Logger.Warning("This will be logged");
- Logger.Error("This will also be logged");
- }
-}
-```
-
## ContextAware 属性生成器
[ContextAware] 属性自动实现 IContextAware 接口,提供便捷的架构上下文访问能力。
@@ -316,7 +296,7 @@ public partial class AdvancedController : IController
### 基础使用
```csharp
-using GFramework.SourceGenerators.Attributes;
+using GFramework.SourceGenerators.Abstractions.enums;
[GenerateEnumExtensions]
public enum GameState
@@ -334,10 +314,12 @@ public static class GameStateExtensions
public static bool IsPaused(this GameState state) => state == GameState.Paused;
public static bool IsGameOver(this GameState state) => state == GameState.GameOver;
public static bool IsMenu(this GameState state) => state == GameState.Menu;
-
+
public static bool IsIn(this GameState state, params GameState[] values)
{
- return values.Contains(state);
+ if (values == null) return false;
+ foreach (var v in values) if (state == v) return true;
+ return false;
}
}
@@ -345,17 +327,17 @@ public static class GameStateExtensions
public class GameManager
{
private GameState _currentState = GameState.Menu;
-
+
public bool CanProcessInput()
{
return _currentState.IsPlaying() || _currentState.IsMenu();
}
-
+
public bool IsGameOver()
{
return _currentState.IsGameOver();
}
-
+
public bool IsActiveState()
{
return _currentState.IsIn(GameState.Playing, GameState.Menu);
@@ -363,15 +345,12 @@ public class GameManager
}
```
-### 自定义扩展方法
+### 配置选项
```csharp
[GenerateEnumExtensions(
- generateIsMethods = true,
- generateHasMethod = true,
- generateInMethod = true,
- customPrefix = "Is",
- includeToString = true
+ GenerateIsMethods = true, // 是否生成 IsX 方法(默认 true)
+ GenerateIsInMethod = true // 是否生成 IsIn 方法(默认 true)
)]
public enum PlayerState
{
@@ -381,84 +360,14 @@ public enum PlayerState
Jumping,
Attacking
}
-
-// 生成更多扩展方法
-public static class PlayerStateExtensions
-{
- public static bool IsIdle(this PlayerState state) => state == PlayerState.Idle;
- public static bool IsWalking(this PlayerState state) => state == PlayerState.Walking;
- public static bool IsRunning(this PlayerState state) => state == PlayerState.Running;
- public static bool IsJumping(this PlayerState state) => state == PlayerState.Jumping;
- public static bool IsAttacking(this PlayerState state) => state == PlayerState.Attacking;
-
- public static bool HasIdle(this PlayerState state) => state == PlayerState.Idle;
- public static bool HasWalking(this PlayerState state) => state == PlayerState.Walking;
- // ... 其他 Has 方法
-
- public static bool In(this PlayerState state, params PlayerState[] values)
- {
- return values.Contains(state);
- }
-
- public static string ToDisplayString(this PlayerState state)
- {
- return state switch
- {
- PlayerState.Idle => "Idle",
- PlayerState.Walking => "Walking",
- PlayerState.Running => "Running",
- PlayerState.Jumping => "Jumping",
- PlayerState.Attacking => "Attacking",
- _ => state.ToString()
- };
- }
-}
-```
-
-### 位标志枚举支持
-
-```csharp
-[GenerateEnumExtensions]
-[Flags]
-public enum PlayerAbilities
-{
- None = 0,
- Jump = 1 << 0,
- Run = 1 << 1,
- Attack = 1 << 2,
- Defend = 1 << 3,
- Magic = 1 << 4
-}
-
-// 生成位标志扩展方法
-public static class PlayerAbilitiesExtensions
-{
- public static bool HasJump(this PlayerAbilities abilities) => abilities.HasFlag(PlayerAbilities.Jump);
- public static bool HasRun(this PlayerAbilities abilities) => abilities.HasFlag(PlayerAbilities.Run);
- // ... 其他位标志方法
-
- public static bool HasAny(this PlayerAbilities abilities, params PlayerAbilities[] flags)
- {
- return flags.Any(flag => abilities.HasFlag(flag));
- }
-
- public static bool HasAll(this PlayerAbilities abilities, params PlayerAbilities[] flags)
- {
- return flags.All(flag => abilities.HasFlag(flag));
- }
-}
```
### 配置选项说明
-| 参数 | 类型 | 默认值 | 说明 |
-|---------------------|--------|-------|------------------------|
-| `generateIsMethods` | bool | true | 是否生成 IsX() 方法 |
-| `generateHasMethod` | bool | true | 是否生成 HasX() 方法 |
-| `generateInMethod` | bool | true | 是否生成 In(params T[]) 方法 |
-| `customPrefix` | string | "Is" | 方法名前缀 |
-| `includeToString` | bool | false | 是否生成 ToString 扩展 |
-| `namespace` | string | null | 生成扩展类的命名空间 |
+| 参数 | 类型 | 默认值 | 说明 |
+|--------------------|------|------|-------------------|
+| GenerateIsMethods | bool | true | 是否为每个枚举值生成 IsX 方法 |
+| GenerateIsInMethod | bool | true | 是否生成 IsIn 方法 |
## 诊断信息
@@ -839,7 +748,7 @@ public enum State
```csharp
// 好的做法:合理的日志级别
-[Log(minLevel = LogLevel.Information)]
+[Log]
public partial class PerformanceCriticalComponent
{
public void Update()
@@ -853,7 +762,7 @@ public partial class PerformanceCriticalComponent
}
// 避免:过度日志记录
-[Log(minLevel = LogLevel.Debug)]
+[Log]
public partial class NoisyComponent
{
public void Update()
@@ -863,47 +772,8 @@ public partial class NoisyComponent
}
```
-#### 2. 延迟上下文初始化
-
-```csharp
-// 好的做法:延迟初始化
-[ContextAware(useLazy = true)]
-public partial class LazyContextComponent : IComponent
-{
- // 只有在第一次访问 Context 时才会初始化
- public void Initialize()
- {
- // 如果这里不需要 Context,就不会初始化
- SomeOtherInitialization();
- }
-}
-```
-
### 🛡️ 错误处理
-#### 1. 上下文验证
-
-```csharp
-[ContextAware(validateContext = true)]
-public partial class SafeContextComponent : IComponent
-{
- public void ProcessData()
- {
- if (Context.IsInvalid)
- {
- Logger.Error("Context is invalid, cannot process data");
- return;
- }
-
- // 安全地使用 Context
- var model = Context.GetModel();
- // ...
- }
-}
-```
-
-#### 2. 异常处理配合
-
```csharp
[Log]
[ContextAware]
diff --git a/docs/zh-CN/source-generators/logging-generator.md b/docs/zh-CN/source-generators/logging-generator.md
index c72c9cf..88bbc44 100644
--- a/docs/zh-CN/source-generators/logging-generator.md
+++ b/docs/zh-CN/source-generators/logging-generator.md
@@ -4,22 +4,21 @@
## 概述
-日志生成器是一个 Source Generator,它会自动为标记了 `[Log]` 特性的类生成 Logger 字段和日志方法调用。这消除了手动编写日志代码的需要,让开发者专注于业务逻辑。
+日志生成器是一个 Source Generator,它会自动为标记了 `[Log]` 特性的类生成 ILogger 字段。这消除了手动编写日志字段的需要,让开发者专注于业务逻辑。
## 基本用法
### 标记类
```csharp
-using GFramework.SourceGenerators.Attributes;
+using GFramework.SourceGenerators.Abstractions.logging;
[Log]
public partial class MyService
{
public void DoSomething()
{
- // 自动生成 Logger 字段
- // 自动生成日志调用
+ // 自动生成的 Logger 字段可直接使用
Logger.Info("执行操作");
}
}
@@ -30,31 +29,19 @@ public partial class MyService
上面的代码会被编译时转换为:
```csharp
+//
public partial class MyService
{
- // 自动生成的字段
- [CompilerGenerated]
- private ILogger _logger;
-
- // 自动生成的属性
- [CompilerGenerated]
- public ILogger Logger
- {
- get
- {
- if (_logger == null)
- {
- _logger = LoggerFactory.CreateLogger();
- }
- return _logger;
- }
- }
+ private static readonly ILogger Logger =
+ LoggerFactoryResolver.Provider.CreateLogger("YourNamespace.MyService");
}
```
+**注意**:生成器只生成 ILogger 字段,不生成日志方法。日志方法(Info、Debug、Error 等)来自 ILogger 接口本身。
+
## 日志级别
-生成的日志方法支持多种级别:
+生成的 Logger 字段支持 ILogger 接口的所有方法:
```csharp
[Log]
@@ -83,7 +70,7 @@ public partial class MyClass
## 自定义日志类别
```csharp
-[Log(LogCategory.Gameplay)]
+[Log("Gameplay")]
public partial class GameplaySystem
{
// 日志会标记为 Gameplay 类别
@@ -94,6 +81,55 @@ public partial class GameplaySystem
}
```
+## 配置选项
+
+### 自定义字段名称
+
+```csharp
+[Log(FieldName = "_customLogger")]
+public partial class MyClass
+{
+ public void DoSomething()
+ {
+ // 使用自定义字段名
+ _customLogger.Info("使用自定义日志器");
+ }
+}
+```
+
+### 非静态字段
+
+```csharp
+[Log(IsStatic = false)]
+public partial class InstanceLogger
+{
+ // 生成实例字段而非静态字段
+ public void LogMessage()
+ {
+ Logger.Info("实例日志");
+ }
+}
+```
+
+### 访问修饰符
+
+```csharp
+[Log(AccessModifier = "protected")]
+public partial class ProtectedLogger
+{
+ // 生成 protected 字段
+}
+```
+
+### 配置选项说明
+
+| 参数 | 类型 | 默认值 | 说明 |
+|----------------|---------|-----------|---------------------------------|
+| Name | string? | null | 日志分类名称(默认使用类名) |
+| FieldName | string | "Logger" | 生成的字段名称 |
+| IsStatic | bool | true | 是否生成静态字段 |
+| AccessModifier | string | "private" | 访问修饰符(private/protected/public) |
+
## 与其他模块集成
### 与 Godot 集成
@@ -123,34 +159,175 @@ public partial class MySystem : AbstractSystem
}
```
-## 配置选项
+## 实际应用示例
-### 禁用自动生成
+### 游戏控制器
```csharp
-// 禁用自动日志调用生成
-[Log(AutoLog = false)]
-public partial class MyClass
+[Log]
+[ContextAware]
+public partial class PlayerController : IController
{
- // 仍会生成 Logger 字段,但不会自动生成日志调用
- public void DoSomething()
+ public void HandleInput(string action)
{
- // 需要手动调用 Logger
- Logger.Info("手动日志");
+ Logger.Debug($"处理输入: {action}");
+
+ switch (action)
+ {
+ case "jump":
+ Logger.Info("玩家跳跃");
+ Jump();
+ break;
+ case "attack":
+ Logger.Info("玩家攻击");
+ Attack();
+ break;
+ default:
+ Logger.Warning($"未知操作: {action}");
+ break;
+ }
+ }
+
+ private void Jump()
+ {
+ try
+ {
+ // 跳跃逻辑
+ Logger.Debug("跳跃执行成功");
+ }
+ catch (Exception ex)
+ {
+ Logger.Error($"跳跃失败: {ex.Message}");
+ }
}
}
```
-### 自定义字段名称
+### 数据处理服务
```csharp
-[Log(FieldName = "_customLogger")]
-public partial class MyClass
+[Log("DataService")]
+public partial class DataProcessor
{
- // Logger 字段名称为 _customLogger
+ public void ProcessData(string data)
+ {
+ Logger.Info($"开始处理数据,长度: {data.Length}");
+
+ if (string.IsNullOrEmpty(data))
+ {
+ Logger.Warning("数据为空,跳过处理");
+ return;
+ }
+
+ try
+ {
+ // 处理逻辑
+ Logger.Debug("数据处理中...");
+ // ...
+ Logger.Info("数据处理完成");
+ }
+ catch (Exception ex)
+ {
+ Logger.Error($"数据处理失败: {ex.Message}");
+ throw;
+ }
+ }
}
```
+## 最佳实践
+
+### 1. 合理使用日志级别
+
+```csharp
+[Log]
+public partial class BestPracticeExample
+{
+ public void ProcessRequest()
+ {
+ // Debug: 详细的调试信息
+ Logger.Debug("开始处理请求");
+
+ // Info: 重要的业务流程信息
+ Logger.Info("请求处理成功");
+
+ // Warning: 可恢复的异常情况
+ Logger.Warning("缓存未命中,使用默认值");
+
+ // Error: 错误但不影响系统运行
+ Logger.Error("处理失败,将重试");
+
+ // Critical: 严重错误,可能导致系统崩溃
+ Logger.Critical("数据库连接失败");
+ }
+}
+```
+
+### 2. 避免过度日志
+
+```csharp
+[Log]
+public partial class PerformanceExample
+{
+ private int _frameCount = 0;
+
+ public void Update()
+ {
+ // 好的做法:定期记录
+ if (_frameCount % 1000 == 0)
+ {
+ Logger.Debug($"已运行 {_frameCount} 帧");
+ }
+ _frameCount++;
+
+ // 避免:每帧都记录
+ // Logger.Debug($"帧 {_frameCount}"); // ❌ 太频繁
+ }
+}
+```
+
+### 3. 结构化日志信息
+
+```csharp
+[Log]
+public partial class StructuredLogging
+{
+ public void ProcessUser(int userId, string action)
+ {
+ // 好的做法:包含上下文信息
+ Logger.Info($"用户操作 [UserId={userId}, Action={action}]");
+
+ // 避免:信息不完整
+ // Logger.Info("用户操作"); // ❌ 缺少上下文
+ }
+}
+```
+
+## 常见问题
+
+### Q: 为什么需要 partial 关键字?
+
+**A**: 源代码生成器需要向现有类添加代码,`partial` 关键字允许一个类的定义分散在多个文件中。
+
+### Q: 可以在静态类中使用吗?
+
+**A**: 可以,生成器会自动生成静态字段:
+
+```csharp
+[Log]
+public static partial class StaticHelper
+{
+ public static void DoSomething()
+ {
+ Logger.Info("静态方法日志");
+ }
+}
+```
+
+### Q: 如何自定义日志工厂?
+
+**A**: 通过配置 `LoggerFactoryResolver.Provider` 来自定义日志工厂实现。
+
---
**相关文档**: