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