子类实现抽象Enum属性遇报错:无法比较Enum与自定义枚举类型
解决Enum与具体枚举类型的==比较错误
这个问题我之前也碰到过,核心原因是基类的CurrentState定义为通用的Enum类型,而子类中使用的是自定义的Player.State枚举,C#不允许直接对Enum基类和具体枚举类型使用==运算符——编译器无法在编译时确认两者的类型兼容性,所以抛出了这个错误。
解决方案1:用泛型基类实现类型安全(推荐)
这是最优雅的方式,让基类针对具体的枚举类型做约束,从根源上避免类型不匹配的问题:
首先修改基类为泛型抽象类,约束泛型参数必须是枚举:
public abstract class Character<TState> : MonoBehaviour where TState : Enum { protected abstract TState CurrentState { get; set; } }
然后让Player类继承时指定自己的State枚举作为泛型参数:
public class Player : Character<Player.State> { protected override Player.State CurrentState { get { return (State)_anim.GetInteger("State"); } set { _anim.SetInteger("State", Convert.ToInt32(value)); } } private enum State { IDLE = 0, WALK = 1, JUMP = 2, FALL = 3, CLIMB = 4, LOOKING_DOWN = 5, NPC = 6, IMPATIENT = 7, LOOKING_UP = 8, STUCK = 9 } void FixedUpdate() { // 现在可以直接比较,不会报错 if (CurrentState == State.CLIMB) { // 你的逻辑代码 } } }
这种方式不仅解决了比较的问题,还让整个状态系统的类型更安全,避免了不必要的类型转换。
解决方案2:在比较时显式转换类型(不修改基类)
如果不想改动基类的结构,可以在比较时把CurrentState强制转换成Player.State类型:
void FixedUpdate() { // 显式转换后再比较 if ((State)CurrentState == State.CLIMB) { // 你的逻辑代码 } }
⚠️ 注意:如果CurrentState的实际值不在Player.State的枚举范围内,强制转换会抛出异常。如果担心这种情况,可以先做合法性检查:
void FixedUpdate() { if (Enum.IsDefined(typeof(State), CurrentState) && (State)CurrentState == State.CLIMB) { // 你的逻辑代码 } }
关于set访问器的疑问
你当前的set访问器里的类型转换是没问题的——value作为Enum类型,通过Convert.ToInt32(value)转换成整数赋值给动画组件的参数是正确的。如果用方案1的泛型方式,value会是具体的Player.State类型,直接转换int会更安全,不需要额外的类型检查。
内容的提问来源于stack exchange,提问作者Sean Carey
相关产品推荐
相关产品推荐

