如何在一个状态下做不同的return

How to do different return in a state

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

所以我在状态机中创建一个状态,我遇到了一个问题,我想跳转到 line 等于 if 语句的状态。但该函数需要默认值 return.

所以我希望它做的是,当我输入“FULL”时,它将进入冰箱状态,但如果我输入“HALF”,那么它应该进入音量状态。

如果 line 不是任何定义的状态,您必须定义。

你有两个选择:

  • 创建并return一个States.NotImplementedState
  • 抛出异常:例如:NotImplementedStateException

对于后者,最好定义自己的异常,这样就可以在父函数中“干净利落地”捕获。


您定义的try/catch没有用。如果出现异常,(此方法的)调用者需要做什么?他应该使用哪个状态?这就是编译器抱怨您需要 return 状态的原因。

只有在您能够“解决”/处理它们时才捕获异常,以便调用者知道该怎么做。如果你不能解决这个方法中的异常,你不应该捕获它。


我会选择例外,因为未知状态是编程错误:

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

另一方面。我读过一些关于“如果我输入 'HALF'”的内容。所以 line 是用户输入。这是一个特殊的状态机。你永远不应该相信用户输入。在这种情况下,最好验证用户是否输入了奇怪的内容。在那种情况下,我可能不会抛出异常,但 return 可以为 null States。考虑 validating/parsing 用户输入并抛出异常,不好。例如:不使用 Convert.ToInt32(userInput),而是使用 int.TryParse(userInput).

可空状态示例:

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

}