簡體   English   中英

覆蓋 C# 派生類中的枚舉

[英]override enum in derived class in C#

我正在創建一個abstract有限機器狀態類,其中包含它可以接收的可能命令的enum ,例如:

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;
        }
    }
}

然后在派生類中,我想覆蓋States中, TransitionsCommands 就像是:

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 ???

好吧, enum實際上是intbyteshortlong等)並且不能被覆蓋。 我建議改用泛型

public abstract class FSMBase<State, Command> 
  where State   : Enum  // : Enum wants C# 7.3+
  where Command : Enum {

  //TODO: I suggest have these fields private, or at least, protected
  public Dictionary<Transition, State> AvailableTransitions;
  public State CurrentState;

  public void ProcessCommand(Command _command) {
    ...
  }

}

在實現MyFSM您可以放置​​所需的枚舉:

public class MyFSM : FSMBase<MyStates, MyCommands> {
  ...
}

編輯:較低的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;
    ... 
  }
  ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM