C#如何泛型传递类作为参数,实现通用怪物状态逻辑复用
问题根因
你定义的PatrolState<T>泛型类没有对类型参数T做任何约束,编译器默认T为object类型,而object类不存在GetMonsterInfo方法,因此编译报错。
解决方案
方案1:基类约束(推荐,所有怪物都继承自Monster适配性最好)
- 首先将公共方法
GetMonsterInfo定义到Monster基类中,子类可以按需重写逻辑:
public abstract class Monster { // 公共方法定义在基类 public abstract void GetMonsterInfo(); }
- 给
PatrolState<T>添加泛型约束,指定T必须是Monster的子类:
public class PatrolState<T> : MonsterBaseState where T : Monster { private T cluster; public PatrolState(T curCluster) { cluster = curCluster; cluster.GetMonsterInfo(); // 现在可以正常调用 } public void BehaviorForUpdate() { // 状态逻辑 } }
- 修正你原有代码里的笔误:
ManyMonster类的Awake方法中,泛型参数填错为Skeleton,需要对应改为自身类型:
public class ManyMonster:Monster { private MonsterBaseState state; private void Awake() { // 泛型参数改为ManyMonster state = new PatrolState<ManyMonster>(this); } public override void GetMonsterInfo() { // 实现自身逻辑 } }
方案2:接口约束(适合只有部分怪物需要实现该方法的场景)
- 定义包含目标方法的接口:
public interface IMonsterInfo { void GetMonsterInfo(); }
- 让需要使用该状态的怪物类实现接口:
public class Skeleton : Monster, IMonsterInfo { public void GetMonsterInfo() { // 自身逻辑 } }
- 给
PatrolState<T>添加接口约束:
public class PatrolState<T> : MonsterBaseState where T : IMonsterInfo { // 其余逻辑和方案1一致 }
扩展优化
如果后续要写更多状态类(比如追击状态、受击状态、死亡状态),可以直接把状态接口也改为泛型,避免重复写约束:
public interface IMonsterState<T> where T : Monster { void BehaviorForUpdate(); } // 后续新状态直接继承泛型接口即可 public class ChaseState<T> : IMonsterState<T> where T : Monster { // 状态逻辑 }
内容的提问来源于stack exchange,提问作者KDYG
相关产品推荐
相关产品推荐

