You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#游戏开发:父类引用调用子类重写方法及消除Switch语句问询

优化游戏单元管理:消除冗余Switch,优雅利用多态

看起来你已经摸到了面向对象优化的门道,你的现有方案已经很好地解决了冗余switch的问题,我来帮你把这个思路梳理得更清晰,同时补充一些细节优势:

问题复盘

你当前的痛点很典型:随着游戏单元类型增加,SpawnUnit、PerformAction里的switch语句会越来越臃肿,而且每次调用子类方法都要手动类型转换,既不优雅也容易出错。你希望把类型判断的逻辑收拢,同时让父类引用能自动触发子类的重写逻辑。

你的优化方案详解

你的思路核心是把类型转换和调度逻辑封装到基类的单一方法中,同时通过多态让子类接管方法执行,这完全符合面向对象的设计原则。

1. 重构后的基类GameUnit

public class GameUnit { 
    public enum UnitType { FighterUnit, MageUnit, Count, } 
    public UnitType type; 
    public virtual void OnUnitSelected() { HighlightUnit(); } 
    // 子类可自定义的方法执行入口,保留扩展空间
    public virtual void RunMethod(Action method) { method(); } 
    // 唯一的类型判断入口,所有子类调度都走这里
    public void DoAsChild(Action method) { 
        switch (type) { 
            case UnitType.FighterUnit: ((FighterUnit)this).RunMethod(method); break; 
            case UnitType.MageUnit: ((MageUnit)this).RunMethod(method); break; 
        } 
    } 
}

这里的关键是DoAsChild方法:它把原来散落在各个业务方法里的类型判断收拢到了基类,后续新增单元类型时,只需要修改这一个地方的switch,避免了代码重复。

2. 子类实现(保持简洁)

public class FighterUnit : GameUnit { 
    public FighterUnit() { type = UnitType.FighterUnit; } 
    public override void OnUnitSelected() { 
        PlayFighterSound(); 
        base.OnUnitSelected(); // 保留基类的高亮逻辑
    } 
    public void Punch() { PunchInfrontOfMe(); } 
    public override void RunMethod(Action method) { method(); } 
} 

public class MageUnit : GameUnit { 
    public MageUnit() { type = UnitType.MageUnit; } 
    public override void OnUnitSelected() { 
        PlayMageSound(); 
        base.OnUnitSelected(); 
    } 
    public void CastSpell() { CreateSpellAtPosition(); } 
    public override void RunMethod(Action method) { method(); } 
}

子类只需要专注于自己的业务逻辑,RunMethod给了子类扩展的空间——比如如果某个子类需要在执行方法前加一些前置检查,直接重写这个方法即可。

3. 业务调用的简化

现在调用子类方法变得非常优雅,不用再到处写switch:

// 触发单元选中逻辑
public void UnitClicked(GameUnit unit) { 
    unit.DoAsChild(unit.OnUnitSelected); 
}

// 执行单元专属动作
public void PerformAction(GameUnit unit) {
    switch (unit.type) {
        case GameUnit.UnitType.FighterUnit: 
            unit.DoAsChild(((FighterUnit)unit).Punch); 
            break;
        case GameUnit.UnitType.MageUnit: 
            unit.DoAsChild(((MageUnit)unit).CastSpell); 
            break;
    }
}

额外进阶优化建议

如果想彻底消除所有switch,可以结合工厂模式+字典映射:

  • 在GameUnitController里维护一个Dictionary<UnitType, Func<GameUnit>>,用来创建不同类型的单元,替代SpawnUnit里的switch;
  • 同时维护一个Dictionary<UnitType, Action<GameUnit>>,把每个单元的专属动作映射进去,这样PerformAction里的switch也可以去掉。

不过你的现有方案已经是非常轻量化的改进,完全能解决当前的问题,适合中小规模的游戏单元系统。

内容的提问来源于stack exchange,提问作者AS_Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:37:36