Почему мой конечный автомат выдает ошибку: неверный переход? - PullRequest
0 голосов
/ 16 марта 2019

Я пытаюсь реализовать конечный автомат.Сценарий таков: если документ отправлен, он отправляется на проверку и после этого утверждается.

Но выдает ошибку, которая рассмотрела -> одобрить переход недействительным.

Вот код, который может дать лучшую картину.

Почему выдает ошибку?Я убедился, что все в порядке, но все же.

 public enum ProcessState
    {    
        Submitted,    
        Reviewed,    
        Approved    
    }  

    public enum Command
    {    
        Submit,    
        Review,    
        Approve    
    }   

    public class Process
    {    
        class StateTransition
        {
            readonly ProcessState CurrentState;    
            readonly Command Command;      

            public StateTransition(ProcessState currentState, Command command)
            {    
                CurrentState = currentState;    
                Command = command;    
            }   

            public override int GetHashCode()
            {    
                return 17 + 31 * CurrentState.GetHashCode() + 31 * Command.GetHashCode();    
            }    

            public override bool Equals(object obj)
            {    
                StateTransition other = obj as StateTransition;    
                return other != null && this.CurrentState == other.CurrentState && this.Command == other.Command;    
            }    
        }    

        Dictionary<StateTransition, ProcessState> transitions;

        public ProcessState CurrentState { get; private set; }   

        public Process()
        {    
            CurrentState = ProcessState.Submitted;    
            transitions = new Dictionary<StateTransition, ProcessState>    
            {    
                 { new StateTransition(ProcessState.Submitted, Command.Review), ProcessState.Reviewed },

            { new StateTransition(ProcessState.Reviewed, Command.Approve), ProcessState.Approved },

            };    
        }   

        public ProcessState GetNext(Command command)
        {    
            StateTransition transition = new StateTransition(CurrentState, command);    
            ProcessState nextState;

            if (!transitions.TryGetValue(transition, out nextState))

                throw new Exception("Invalid transition: " + CurrentState + " -> " + command);

            return nextState;    
        }    

        public ProcessState MoveNext(Command command)
        {    
            CurrentState = GetNext(command);    
            return CurrentState;    
        }    
    }    

    public class Program
    {   
        static void Main(string[] args)
        {    
            Process p = new Process();

            Console.WriteLine("Current State = " + p.CurrentState);    
            Console.WriteLine("Command.Submit: Current State = " + p.MoveNext(Command.Submit));    
            Console.WriteLine("Command.Review: Current State = " + p.MoveNext(Command.Review));    
            Console.WriteLine("Command.Approve: Current State = " + p.MoveNext(Command.Approve));    
            Console.ReadLine();  
        }    
    }

Обновление:

Вот часть ошибки:

  public ProcessState GetNext(Command command)
        {

            StateTransition transition = new StateTransition(CurrentState, command);

            ProcessState nextState;

            if (!transitions.TryGetValue(transition, out nextState))

                throw new Exception("Invalid transition: " + CurrentState + " -> " + command);

            return nextState;

        }

1 Ответ

1 голос
/ 16 марта 2019

Это позволяет вашему примеру Main работать правильно.Проблема в том, что в вашем словаре transitions нет записи для Command.Approve.

public Process()
{
    CurrentState = ProcessState.Submitted;
    transitions = new Dictionary<StateTransition, ProcessState>
    {
        //This does nothing.  Submitted -> Submitted
        { new StateTransition(ProcessState.Submitted, Command.Submit), ProcessState.Submitted },
        //Submitted -> Reviewed
        { new StateTransition(ProcessState.Submitted, Command.Review), ProcessState.Reviewed },
        //Reviewed -> Submitted.  Do you want this?
        { new StateTransition(ProcessState.Reviewed, Command.Submit), ProcessState.Submitted },
        //I added this.  Reviewed -> Approved
        { new StateTransition(ProcessState.Reviewed, Command.Approve), ProcessState.Approved }
    };
}

Выходы:

Command.Submit: Текущее состояние = Отправлено

Command.Review: текущее состояние = проверено

Command.Approve: текущее состояние = утверждено

Примечание. Я не проверял все переходы конечного автомата.Я просто добавил недостающий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...