C# 重写C中派生类中的枚举

C# 重写C中派生类中的枚举,c#,enums,derived-class,C#,Enums,Derived Class,我正在创建一个抽象的有限机器状态类,其中包含它可以接收的可能命令的枚举,例如: public abstract class FSMBase { public enum Commands {}; public enum States; public Dictionary<Transition, States> AvailableTransitions; public States CurrentState; public abstract vo

我正在创建一个抽象的有限机器状态类,其中包含它可以接收的可能命令的枚举,例如:

public abstract class FSMBase
{
    public enum Commands {};
    public enum States;
    public Dictionary<Transition, States> AvailableTransitions;
    public States CurrentState;

    public abstract void InitCommandsAndStatesAndTransitiosnAndInitialState();

    public void ProcessCommand(Commands _command)
    {
        Transition RequestedTransition = new Transition(CurrentState, command);
        if(AvailableTransitions.TryGetValue(RequestedTransition, out State nextState) //pseudocode
        {
             CurrentState = nextState;
        }
    }
}
public class MyFSM : FSMBase
{
    public override void InitCommandsAndStatesAndTransitiosnAndInitialState()
    {
        States = {Off, starting, started, ...} //HERE IS MY PROBLEM
        Commands = {start, stop, finish, ...}; // HERE IS MY PROBLEM

        Transitions = new Dictionary<Transition, BaseState>
        {
            {new Transition(States.Off, Commands.Start), States.starting},
            ....
        }

        CurrentState = States.Off;
    }
}
如何覆盖派生类中的枚举

嗯,enum实际上是int字节、短字节、长字节等。不能被覆盖。我建议改用泛型

编辑:对于较低的c版本,您可以尝试相同的想法,但有不同的限制:

public abstract class FSMBase<State, Command> 
  where State   : struct  
  where Command : struct {

  public State CurrentState;
  ...        

  // Instead of compile time error we are going to have runtime one,
  // if either State or Command is not enum
  static FSMBase() {
    if (!typeof(State).IsEnum)
      throw new InvalidCastException("Generic pararameter State must be enum!");
    else if (!typeof(Command).IsEnum)
      throw new InvalidCastException("Generic pararameter Command must be enum!");
  }
}

...

public class MyFSM : FSMBase<MyStates, MyCommands> {
  public override void InitCommandsAndStatesAndTransitiosnAndInitialState() {
    ...
    CurrentState = MyStates.Off;
    ... 
  }
  ...
}
嗯,枚举实际上是int字节,短,长等。不能被覆盖。我建议改用泛型

编辑:对于较低的c版本,您可以尝试相同的想法,但有不同的限制:

public abstract class FSMBase<State, Command> 
  where State   : struct  
  where Command : struct {

  public State CurrentState;
  ...        

  // Instead of compile time error we are going to have runtime one,
  // if either State or Command is not enum
  static FSMBase() {
    if (!typeof(State).IsEnum)
      throw new InvalidCastException("Generic pararameter State must be enum!");
    else if (!typeof(Command).IsEnum)
      throw new InvalidCastException("Generic pararameter Command must be enum!");
  }
}

...

public class MyFSM : FSMBase<MyStates, MyCommands> {
  public override void InitCommandsAndStatesAndTransitiosnAndInitialState() {
    ...
    CurrentState = MyStates.Off;
    ... 
  }
  ...
}

ups,看起来不错,但我被限制在4.7.1:@javirs:.Net框架版本和c语言版本是不同的东西;你可以使用4.7.1平台和C7.3:Ups。。我真的什么都不知道:无论如何,我在这两方面都受到约束,编译器说:约束不能是特殊的类Enum,所以。。我猜C也低于7。3@javirs:如果C7.3不是选项,您可以尝试:struct constraint和static constructor来验证泛型类型是否为枚举;请看我的编辑它确实有用我创建了FSMBase,它完全按照我想要的那样工作:ups,看起来不错,但我被限制在4.7.1:@javirs:.Net框架版本和c语言版本是不同的东西;你可以使用4.7.1平台和C7.3:Ups。。我真的什么都不知道:无论如何,我在这两方面都受到约束,编译器说:约束不能是特殊的类Enum,所以。。我猜C也低于7。3@javirs:如果C7.3不是选项,您可以尝试:struct constraint和static constructor来验证泛型类型是否为枚举;请看我的编辑它确实有用我创建了FSMBase,它完全按照我想要的方式工作:我想说enum可以实现FSM,但它有一个弱点——当需要重用性时,它是有限的。由于您试图创建通用FSM,我建议您使用hum。。我不得不同意。。我想将进入和退出操作添加到我的状态和。。在这种情况下,这感觉像是一种黑客行为。对于这种情况,字典通常更合适。你有点像登记处。您可以注册字符串,在内部使用相应的索引,在外部或文档中,仍然可以使用字符串。您也可以只使用const int Off=1,const int On=2,这是可以扩展到MaxInt的。我想说,enum可以实现FSM,但它有一个弱点——当需要重用性时,它是有限的。由于您试图创建通用FSM,我建议您使用hum。。我不得不同意。。我想将进入和退出操作添加到我的状态和。。在这种情况下,这感觉像是一种黑客行为。对于这种情况,字典通常更合适。你有点像登记处。您可以注册字符串,在内部使用相应的索引,在外部或文档中,仍然可以使用字符串。也可以只使用constintoff=1,constinton=2,这可以扩展到MaxInt。
public abstract class FSMBase<State, Command> 
  where State   : struct  
  where Command : struct {

  public State CurrentState;
  ...        

  // Instead of compile time error we are going to have runtime one,
  // if either State or Command is not enum
  static FSMBase() {
    if (!typeof(State).IsEnum)
      throw new InvalidCastException("Generic pararameter State must be enum!");
    else if (!typeof(Command).IsEnum)
      throw new InvalidCastException("Generic pararameter Command must be enum!");
  }
}

...

public class MyFSM : FSMBase<MyStates, MyCommands> {
  public override void InitCommandsAndStatesAndTransitiosnAndInitialState() {
    ...
    CurrentState = MyStates.Off;
    ... 
  }
  ...
}