# Extensions 包使用说明 ## 概述 Extensions 包提供了一系列扩展方法,简化了框架各个接口的使用。通过扩展方法,可以用更简洁的语法访问框架功能,提高代码可读性和开发效率。 ## 扩展方法类别 ### 1. ContextAware 扩展 ([`ContextAwareExtensions.cs`](ContextAwareExtensions.cs)) 为 [`IContextAware`](../../GFramework.Core.Abstractions/rule/IContextAware.cs) 提供扩展方法,允许直接从实现了 [IContextAware](file:///d:/Project/Rider/GFramework/GFramework.Core.Abstractions/rule/IContextAware.cs) 的对象获取架构组件。 #### GetSystem 扩展方法 ```csharp public static TSystem? GetSystem(this IContextAware contextAware) where TSystem : class, ISystem ``` **使用示例:** ```csharp // 在实现了 IContextAware 的类中使用 public class PlayerController : IController { public void UpdateUI() { // 直接通过 this 调用 var playerSystem = this.GetSystem(); var inventorySystem = this.GetSystem(); } } ``` #### GetModel 扩展方法 ```csharp public static TModel? GetModel(this IContextAware contextAware) where TModel : class, IModel ``` **使用示例:** ```csharp public class PlayerController : IController { public void UpdateStats() { // 获取模型 var playerModel = this.GetModel(); var inventoryModel = this.GetModel(); // 使用模型数据 playerModel.Health += 10; } } ``` #### GetUtility 扩展方法 ```csharp public static TUtility? GetUtility(this IContextAware contextAware) where TUtility : class, IUtility ``` **使用示例:** ```csharp public class GameModel : AbstractModel, IContextAware { protected override void OnInit() { // 获取工具 var timeUtility = this.GetUtility(); var storageUtility = this.GetUtility(); } } ``` #### SendCommand 扩展方法 ```csharp // 发送无返回值的命令 public static void SendCommand(this IContextAware contextAware, ICommand command) // 发送带返回值的命令 public static TResult SendCommand(this IContextAware contextAware, ICommand command) ``` **使用示例:** ```csharp public class GameController : IController { public void OnStartButtonClicked() { // 发送命令实例 this.SendCommand(new StartGameCommand()); // 发送带返回值的命令 var result = this.SendCommand(new CalculateScoreCommand()); } } ``` #### SendQuery 扩展方法 ```csharp public static TResult SendQuery(this IContextAware contextAware, IQuery query) ``` **使用示例:** ```csharp public class InventoryController : IController { public void ShowInventory() { // 发送查询获取数据 var items = this.SendQuery(new GetInventoryItemsQuery()); var gold = this.SendQuery(new GetPlayerGoldQuery()); UpdateInventoryUI(items, gold); } } ``` #### SendEvent 扩展方法 ```csharp // 发送无参事件 public static void SendEvent(this IContextAware contextAware) where T : new() // 发送事件实例 public static void SendEvent(this IContextAware contextAware, T e) where T : class ``` **使用示例:** ```csharp public class PlayerModel : AbstractModel, IContextAware { public void TakeDamage(int damage) { Health -= damage; if (Health <= 0) { // 方式1:发送无参事件 this.SendEvent(); // 方式2:发送带数据的事件 this.SendEvent(new PlayerDiedEvent { Position = Position, Cause = "Damage" }); } } } ``` #### RegisterEvent 扩展方法 ```csharp public static IUnRegister RegisterEvent(this IContextAware contextAware, Action handler) ``` **使用示例:** ```csharp public class GameController : IController { private IUnRegisterList _unregisterList = new UnRegisterList(); public void Initialize() { // 注册事件监听 this.RegisterEvent(OnGameStarted) .AddToUnregisterList(_unregisterList); this.RegisterEvent(OnPlayerLevelUp) .AddToUnregisterList(_unregisterList); } private void OnGameStarted(GameStartedEvent e) { } private void OnPlayerLevelUp(PlayerLevelUpEvent e) { } } ``` #### UnRegisterEvent 扩展方法 ```csharp public static void UnRegisterEvent(this IContextAware contextAware, Action onEvent) ``` ### GetEnvironment 扩展方法 ```csharp public static T? GetEnvironment(this IContextAware contextAware) where T : class public static IEnvironment GetEnvironment(this IContextAware contextAware) ``` ### 2. Object 扩展 ([`ObjectExtensions.cs`](ObjectExtensions.cs)) 提供基于运行时类型判断的对象扩展方法,用于简化类型分支、链式调用和架构分派逻辑。 #### IfType 扩展方法 ```csharp // 最简单的类型判断 public static bool IfType(this object obj, Action action) // 带条件的类型判断 public static bool IfType( this object obj, Func predicate, Action action ) // 条件判断,带不匹配时的处理 public static void IfType( this object obj, Action whenMatch, Action? whenNotMatch = null ) ``` **使用示例:** ```csharp object obj = new MyRule(); // 简单类型判断 bool executed = obj.IfType(rule => { rule.Initialize(); }); // 带条件的类型判断 obj.IfType( r => r.Enabled, // 条件 r => r.Execute() // 执行动作 ); // 带不匹配处理的类型判断 obj.IfType( rule => rule.Execute(), other => Logger.Warn($"Unsupported type: {other.GetType()}") ); ``` #### IfType 扩展方法 ```csharp public static TResult? IfType( this object obj, Func func ) ``` **使用示例:** ```csharp object obj = new MyRule { Name = "TestRule" }; string? name = obj.IfType(r => r.Name); ``` #### As 和 Do 扩展方法 ```csharp // 安全类型转换 public static T? As(this object obj) where T : class // 流式调用 public static T Do(this T obj, Action action) ``` **使用示例:** ```csharp // 安全类型转换 obj.As() ?.Execute(); // 流式调用 obj.As() ?.Do(r => r.Initialize()) ?.Do(r => r.Execute()); // 组合使用 obj.As() ?.Do(rule => { if (rule.Enabled) rule.Execute(); }); ``` #### SwitchType 扩展方法 ```csharp public static void SwitchType( this object obj, params (Type type, Action action)[] handlers ) ``` **使用示例:** ```csharp obj.SwitchType( (typeof(IRule), o => HandleRule((IRule)o)), (typeof(ISystem), o => HandleSystem((ISystem)o)), (typeof(IModel), o => HandleModel((IModel)o)) ); ``` ### 3. OrEvent 扩展 ([`OrEventExtensions.cs`](OrEventExtensions.cs)) 为 [`IEvent`](../../GFramework.Core.Abstractions/events/IEvent.cs) 提供事件组合功能。 #### OrEventExtensions ```csharp public static OrEvent Or(this IEvent self, IEvent e) ``` **使用示例:** ```csharp // 组合多个事件:当任意一个触发时执行 var onAnyInput = onKeyPressed.Or(onMouseClicked).Or(onTouchDetected); onAnyInput.Register(() => { GD.Print("Any input detected!"); }); // 链式组合 var onAnyDamage = onPhysicalDamage .Or(onMagicDamage) .Or(onPoisonDamage); ``` ### 4. UnRegisterList 扩展 ([`UnRegisterListExtension.cs`](UnRegisterListExtension.cs)) 为 [`IUnRegister`](../events/IUnRegister.cs) 和 [`IUnRegisterList`](../events/IUnRegisterList.cs) 提供批量管理功能。 #### UnRegisterListExtension ```csharp // 添加到注销列表 public static void AddToUnregisterList(this IUnRegister self, IUnRegisterList unRegisterList) // 批量注销 public static void UnRegisterAll(this IUnRegisterList self) ``` **使用示例:** ```csharp public class ComplexController : IController { private IUnRegisterList _unregisterList = new UnRegisterList(); public void Initialize() { // 所有注册都添加到列表中 this.RegisterEvent(OnEvent1) .AddToUnregisterList(_unregisterList); this.RegisterEvent(OnEvent2) .AddToUnregisterList(_unregisterList); this.GetModel().Property1.Register(OnProperty1Changed) .AddToUnregisterList(_unregisterList); this.GetModel().Property2.Register(OnProperty2Changed) .AddToUnregisterList(_unregisterList); } public void Cleanup() { // 一次性注销所有 _unregisterList.UnRegisterAll(); } } ``` ## 完整使用示例 ### Controller 示例 ```csharp public partial class GameplayController : IController { private IUnRegisterList _unregisterList = new UnRegisterList(); public void Initialize() { // 使用扩展方法获取 Model var playerModel = this.GetModel(); var gameModel = this.GetModel(); // 使用扩展方法注册事件 this.RegisterEvent(OnGameStarted) .AddToUnregisterList(_unregisterList); // 监听可绑定属性 playerModel.Health.Register(OnHealthChanged) .AddToUnregisterList(_unregisterList); } public void Process(double delta) { // 发送命令 this.SendCommand(new AttackCommand(targetId: 1)); // 发送查询 var hasPotion = this.SendQuery(new HasItemQuery("health_potion")); if (hasPotion) { this.SendCommand(); } } private void OnGameStarted(GameStartedEvent e) { Console.WriteLine("Game started!"); } private void OnHealthChanged(int health) { UpdateHealthBar(health); } public void Cleanup() { _unregisterList.UnRegisterAll(); } } ``` ### Command 示例 ```csharp public class ComplexGameCommand : AbstractCommand { protected override void OnExecute() { // 获取多个组件 var playerModel = this.GetModel(); var gameSystem = this.GetSystem(); var timeUtility = this.GetUtility(); // 执行业务逻辑 var currentTime = timeUtility.GetCurrentTime(); gameSystem.ProcessGameLogic(playerModel, currentTime); // 发送事件通知 this.SendEvent(new GameStateChangedEvent()); // 可以发送其他命令(谨慎使用) this.SendCommand(); } } ``` ### System 示例 ```csharp public class AchievementSystem : AbstractSystem { protected override void OnInit() { // 注册事件监听 this.RegisterEvent(OnEnemyKilled); this.RegisterEvent(OnLevelCompleted); } private void OnEnemyKilled(EnemyKilledEvent e) { // 获取模型 var playerModel = this.GetModel(); playerModel.EnemyKillCount++; // 检查成就 if (playerModel.EnemyKillCount >= 100) { // 发送成就解锁事件 this.SendEvent(new AchievementUnlockedEvent { AchievementId = "kill_100_enemies" }); } } private void OnLevelCompleted(LevelCompletedEvent e) { // 发送查询 var completionTime = this.SendQuery(new GetLevelTimeQuery(e.LevelId)); if (completionTime < 60) { this.SendEvent(new AchievementUnlockedEvent { AchievementId = "speed_runner" }); } } } ``` ## 扩展方法的优势 1. **简洁的语法** :不需要显式调用 [GetContext()](file:///d:/Project/Rider/GFramework/GFramework.Core.Abstractions/rule/IContextAware.cs#L13-L15) 2. **类型安全**:编译时检查类型 3. **可读性高**:代码意图更清晰 4. **智能提示**:IDE 可以提供完整的自动补全 5. **链式调用**:支持流式编程风格 ## 注意事项 1. **确保引用命名空间:** ```csharp using GFramework.Core.extensions; ``` 2. **理解扩展方法本质:** - 扩展方法是静态方法的语法糖 - 不会改变原始类型的结构 - 仅在编译时解析 3. **性能考虑:** - 扩展方法本身无性能开销 - 实际调用的是底层方法 ## 相关包 - [`architecture`](../architecture/README.md) - 扩展方法最终调用架构方法 - [`command`](../command/README.md) - 命令发送扩展 - [`query`](../query/README.md) - 查询发送扩展 - [`events`](../events/README.md) - 事件注册和 Or 组合扩展 - [`model`](../model/README.md) - 模型获取扩展 - [`system`](../system/README.md) - 系统获取扩展 - [`utility`](../utility/README.md) - 工具获取扩展