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

C#如何泛型传递类作为参数,实现通用怪物状态逻辑复用

问题根因

你定义的PatrolState<T>泛型类没有对类型参数T做任何约束,编译器默认T为object类型,而object类不存在GetMonsterInfo方法,因此编译报错。

解决方案

方案1:基类约束(推荐,所有怪物都继承自Monster适配性最好)

  1. 首先将公共方法GetMonsterInfo定义到Monster基类中,子类可以按需重写逻辑:
public abstract class Monster
{
    // 公共方法定义在基类
    public abstract void GetMonsterInfo();
}
  1. 给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()
    {
        // 状态逻辑
    }
}
  1. 修正你原有代码里的笔误:ManyMonster类的Awake方法中,泛型参数填错为Skeleton,需要对应改为自身类型:
public class ManyMonster:Monster 
{
    private MonsterBaseState state;
    private void Awake()
    {
        // 泛型参数改为ManyMonster
        state = new PatrolState<ManyMonster>(this);
    }
    public override void GetMonsterInfo()
    {
        // 实现自身逻辑
    }
}

方案2:接口约束(适合只有部分怪物需要实现该方法的场景)

  1. 定义包含目标方法的接口:
public interface IMonsterInfo
{
    void GetMonsterInfo();
}
  1. 让需要使用该状态的怪物类实现接口:
public class Skeleton : Monster, IMonsterInfo
{
    public void GetMonsterInfo()
    {
        // 自身逻辑
    }
}
  1. 给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:15:06