Home > Enterprise >  How to do different return in a state
How to do different return in a state

Time:06-05

            States TypeState()
            {
                try
                {
                    if (line == "FULL")
                    {
                        streamWriter.WriteLine("FRIDGE");
                        streamWriter.Flush();
                        return States.Fridge;
                    }
                    else if (line == "HALF")
                    {
                        streamWriter.WriteLine("VOLUME");
                        streamWriter.Flush();
                        return States.Volume;
                    }
                    else if (line == "QUART")
                    {
                        //currentState = States.initializationState;
                        streamWriter.WriteLine("ACK");
                        Report.AddContainerQuarterSize(originCountry, descriptionContents);
                        streamWriter.Flush();
                        //CloseConnection(); closeing function not here yet
                        //CloseConnection(); is also a generate report to end the session.
                    }
                    else
                    {
                        throw new ContainerCommandException();
                    }
                }
                catch (ContainerCommandException pce)
                {
                    streamWriter.WriteLine(pce.Message);
                    streamWriter.Flush();
                }
            }

so im making a state in a state machine and i have come across a problem that i want to jump to a state where line is equal to the if statement. but the function wants a default return.

So what i expect it to do is when i type "FULL" it will go to the Fridge state but if I type "HALF" then it should go to the Volume state.

CodePudding user response:

You have to define if the line isn't any of the defined states.

You have two options:

  • Create and return a States.NotImplementedState
  • Throw an exception: For example: NotImplementedStateException

For the latter, it is best to define your own exception, so that you can "cleanly" catch it in a parent function.


The try/catch you've defined is not useful. What does the caller (of this method) need to do if there is an exception? Which state should he use? That's why the compiler is complaining you need to return a State.

Only catch exceptions if you're able to "solve"/handle them so that the caller know what to do. If you can't solve the exception in this method, you shouldn't catch it.


I would go for the exception, because an unknown state is a programming mistake:

States TypeState()
{
    switch(line)
    {
        case "FULL":
            streamWriter.WriteLine("FRIDGE");
            streamWriter.Flush();
            return States.Fridge;

        case "HALF":
            streamWriter.WriteLine("VOLUME");
            streamWriter.Flush();
            return States.Volume;
    
        case "QUART":
            //currentState = States.initializationState;
            streamWriter.WriteLine("ACK");
            Report.AddContainerQuarterSize(originCountry, descriptionContents);
            streamWriter.Flush();
            //CloseConnection(); closeing function not here yet
            //CloseConnection(); is also a generate report to end the session.
            
            // YOU MUST RETURN A State here.
            return States.SomethingUseful;

        default:
            throw new NotImplementedState($"State '{line}' is not implemented");
    }
}

On the other hand. I've read something about "If I type 'HALF'". So line is user input. It's a special state machine. You should never trust user input. In that case, it's better to validate whether the user typed something strange. In that case I might not throw an exception, but return a nullable States. Consider validating/parsing userinput and throwing exceptions on that, bad. For example: instead of using Convert.ToInt32(userInput), use int.TryParse(userInput).

Nullable States example:

States? TypeState(string line)
{
    switch(line)
    {
        case "FULL":
            streamWriter.WriteLine("FRIDGE");
            streamWriter.Flush();
            return States.Fridge;

        case "HALF":
            streamWriter.WriteLine("VOLUME");
            streamWriter.Flush();
            return States.Volume;
    
        case "QUART":
            //currentState = States.initializationState;
            streamWriter.WriteLine("ACK");
            Report.AddContainerQuarterSize(originCountry, descriptionContents);
            streamWriter.Flush();
            //CloseConnection(); closeing function not here yet
            //CloseConnection(); is also a generate report to end the session.
            
            // YOU MUST RETURN A State here.
            return States.SomethingUseful;

        default:
            return null;
    }
}

Call it like:


while(true)
{
    var line = CallSomeInputMethod().ToUpper();
    
    var newState = TypeState(line);
    
    if(!newState.HasValue)
    {
        streamWriter.WriteLine("You've entered an unknown state. Try again:");
        streamWriter.Flush();
        continue;
    }

    switch(newState.Value)
    {
        case newState.Volume:
            // etc etc
            break;
    }

}
  •  Tags:  
  • c#
  • Related