更新:
再次感谢您提供的示例,它们非常有帮助,对于以下内容,我不是说 拿走他们的任何东西。
就我对它们和状态机的理解,目前给出的例子难道不是我们通常理解的状态机的一半吗?
从某种意义上说,示例确实会改变状态,但这只是通过改变变量的值(并允许在不同状态下进行不同的值改变)来表示,而通常情况下,状态机也应该改变它的行为,而行为不(仅)在允许变量根据状态更改不同值的意义上,但在允许针对不同状态执行不同方法的意义上。
还是我对状态机及其常见用途有误解?
原始问题:
我发现了关于 state machines & iterator blocks in c# 的讨论以及为 C# 创建状态机等的工具,所以我发现了很多抽象的东西,但作为菜鸟,所有这些都有点令人困惑。
因此,如果有人可以提供一个 C# 源代码示例,它实现了一个可能具有 3,4 个状态的简单状态机,只是为了了解它的要点,那就太好了。
最佳答案
让我们从这个简单的状态图开始:
我们有:
- 4 种状态(不活动、事件、暂停和退出)
- 5 种状态转换(开始命令、结束命令、暂停命令、恢复命令、退出命令)。
您可以通过多种方式将其转换为 C#,例如对当前状态和命令执行 switch 语句,或在转换表中查找转换。对于这个简单的状态机,我更喜欢转换表,它很容易用 Dictionary
表示:
using System;
using System.Collections.Generic;
namespace Juliet
{
public enum ProcessState
{
Inactive,
Active,
Paused,
Terminated
}
public enum Command
{
Begin,
End,
Pause,
Resume,
Exit
}
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.Inactive;
transitions = new Dictionary<StateTransition, ProcessState>
{
{ new StateTransition(ProcessState.Inactive, Command.Exit), ProcessState.Terminated },
{ new StateTransition(ProcessState.Inactive, Command.Begin), ProcessState.Active },
{ new StateTransition(ProcessState.Active, Command.End), ProcessState.Inactive },
{ new StateTransition(ProcessState.Active, Command.Pause), ProcessState.Paused },
{ new StateTransition(ProcessState.Paused, Command.End), ProcessState.Inactive },
{ new StateTransition(ProcessState.Paused, Command.Resume), ProcessState.Active }
};
}
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.Begin: Current State = " + p.MoveNext(Command.Begin));
Console.WriteLine("Command.Pause: Current State = " + p.MoveNext(Command.Pause));
Console.WriteLine("Command.End: Current State = " + p.MoveNext(Command.End));
Console.WriteLine("Command.Exit: Current State = " + p.MoveNext(Command.Exit));
Console.ReadLine();
}
}
}
根据个人喜好,我喜欢用 GetNext
函数设计我的状态机以返回下一个状态 deterministically , 和一个 MoveNext
函数来改变状态机。
关于c# - C# 中的简单状态机示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5923767/