C#如何让继承的泛型类仅为指定的两种泛型类型之一?
解决方案
你原来的泛型约束写法存在逻辑错误:where T : StatusManager<PlayerStatusModel>, StatusManager<MobStatusModel>要求T同时继承两个类,但C#是单继承语言,这根本无法实现;而且你的T应该是PlayerStatusModel或MobStatusModel,而非StatusManager的子类。
下面提供两种符合需求的实现方式,优先推荐第一种:
方式一:创建专属的HealthManager子类(最严格且符合需求)
直接针对两种角色类型分别定义HealthManager,从根源上限制只能使用这两种父类,同时能方便地为Mob添加专属特性:
// 玩家专属健康管理器 public class PlayerHealthManager : StatusManager<PlayerStatusModel> { // 这里可以添加玩家独有的健康逻辑,比如回血技能触发、UI同步等 } // 怪物专属健康管理器 public class MobHealthManager : StatusManager<MobStatusModel> { // 这里添加怪物专属的健康特性,比如死亡掉落、仇恨清除等,完全符合你“Mob仅应具备相关特性”的要求 }
这种方式在编译阶段就严格限制了HealthManager的继承范围,开发者无法创建其他类型的HealthManager,同时不同角色的健康逻辑可以完全隔离,扩展性更好。
方式二:基于共同基类的泛型约束(适合需要通用逻辑的场景)
如果需要保留HealthManager的泛型特性,可以先让PlayerStatusModel和MobStatusModel继承同一个抽象基类,再通过泛型约束限制范围:
第一步:定义基类
// 所有状态模型的抽象基类 public abstract class BaseStatusModel : MonoBehaviour { // 定义两种模型共有的属性,比如当前生命值、最大生命值等 public int CurrentHealth { get; set; } public int MaxHealth { get; set; } } // 玩家状态模型继承基类 public class PlayerStatusModel : BaseStatusModel { // 玩家专属属性,比如护甲值、吸血比例等 } // 怪物状态模型继承基类 public class MobStatusModel : BaseStatusModel { // 怪物专属属性,比如攻击仇恨值、死亡经验值等 }
第二步:修改HealthManager的泛型约束
public class HealthManager<T> : StatusManager<T> where T : BaseStatusModel { protected void Start() { // 可以通过类型判断执行不同角色的专属逻辑 if (model is MobStatusModel mobModel) { // 执行怪物专属逻辑,比如初始化仇恨值 } else if (model is PlayerStatusModel playerModel) { // 执行玩家专属逻辑,比如绑定UI控件 } } // 通用健康逻辑,比如受伤处理、死亡判断 public void TakeDamage(int damage) { model.CurrentHealth -= damage; if (model.CurrentHealth <= 0) { OnDeath(); } } protected virtual void OnDeath() { // 可以在子类中重写,实现不同角色的死亡逻辑 } }
注意:这种方式编译阶段只能限制T是BaseStatusModel的子类,如果后续新增其他状态模型,依然可以被用作HealthManager的泛型参数,因此不如第一种方式严格。
内容的提问来源于stack exchange,提问作者Jamelaumn
相关产品推荐
相关产品推荐

