0

I am just new to state machines and tried my hands on the process of Submit, Review and Approved scenario using state machines. It throws error on fsm.ProcessEvent(FiniteStateMachine.Events.Reviewed);

i.e. object reference null exception. I cannot figure out? Am I implementing the scenario correctly?

    class Program
    {
        static void Main(string[] args)
        {
            var fsm = new FiniteStateMachine();
            Console.WriteLine(fsm.State);
            fsm.ProcessEvent(FiniteStateMachine.Events.Submitted);
            Console.WriteLine(fsm.State);
            fsm.ProcessEvent(FiniteStateMachine.Events.Reviewed);
            Console.WriteLine(fsm.State);
            fsm.ProcessEvent(FiniteStateMachine.Events.Approved);
            Console.WriteLine(fsm.State);
            Console.ReadKey();
        }

        class FiniteStateMachine
        {
            public enum States { Submitted, Reviewed, Approved};
            public States State { get; set; }

            public enum Events { Submitted, Reviewed, Approved};

            private Action[,] fsm;

            public FiniteStateMachine()
            {
                this.fsm = new Action[3, 3] { 
                //Submitted,    Reviewed,               TurnOff,           
                {this.SubmittedForReview,   null,                   null               },     //Submitted
                {null,          this.Reviewing,          null              },     //Reviewed
                {null,          null,                   this.Approving} };       //Approved
            }

            public void ProcessEvent(Events theEvent)
            {
                this.fsm[(int)this.State, (int)theEvent].Invoke();
            }

            private void SubmittedForReview() { this.State = States.Submitted; }
            private void Reviewing() { this.State = States.Reviewed; }
            private void Approving() { this.State = States.Approved; }
        }
    }
}
Stacky
  • 55
  • 7
  • 2
    Possible duplicate of [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) –  Mar 16 '19 at 11:06

2 Answers2

0

I think the problem is with your FSM. You're creating a multidimensional array of actions. Instead try a look up, like a dictionary. Here you have a dictionary where the key is the status and the value is the action you want to take. This worked for me. Here's what I changed.

    private Dictionary<int, Action> fsm;

    public FiniteStateMachine()
    {
        this.fsm = new Dictionary<int, Action>() {
        { (int)States.Submitted, SubmittedForReview },
            {(int)States.Reviewed, Reviewing },
            {(int)States.Approved, Approving}
            };
    }

    public void ProcessEvent(Events theEvent)
    {
        var action = fsm[(int)theEvent];
        action.Invoke();
    }

EDIT 1

The reason you're getting a null reference when processing Reviewed is because the State is set to Submitted. Enums in C# start at 0 so when you call

 fsm.ProcessEvent(FiniteStateMachine.Events.Reviewed);

what are you trying to look up is

 public void ProcessEvent(Events theEvent)
    {
        //this.fsm[(int)this.State, (int)theEvent].Invoke();
        this.fsm[0, 1].Invoke();
    }

because this.State is still Submitted. So you are trying to Invoke the action at index 1 of the index 0 which is null. Hope that helps.

Sean
  • 819
  • 7
  • 15
0

in your case it's normal to have an object reference null exception because you haven't an event for Reviewed for state Submitted you need to arrange your array.

you can use the code below to avoid object reference null exception (feature of c# 6)

    public void ProcessEvent(Events theEvent)
    {
        this.fsm[(int)this.State, (int)theEvent]?.Invoke();
    }
sayah imad
  • 1,399
  • 3
  • 14
  • 22