C# 动态状态机的More.net方法
我写了一个简单的动态FSM<代码>动态表示状态转换是动态的,而不是静态的,如C# 动态状态机的More.net方法,c#,.net,winforms,design-patterns,state-machine,C#,.net,Winforms,Design Patterns,State Machine,我写了一个简单的动态FSM动态表示状态转换是动态的,而不是静态的,如ConcreteStateB所示 namespace FSM_Example { using System; class Program { static void Main() { var context = new Context(new ConcreteStateA()); context.Run();
ConcreteStateB
所示
namespace FSM_Example
{
using System;
class Program
{
static void Main()
{
var context = new Context(new ConcreteStateA());
context.Run();
Console.Read();
}
}
abstract class State
{
public abstract void Execute(Context context);
}
class ConcreteStateA : State
{
public override void Execute(Context context)
{
context.State = new ConcreteStateB();
}
}
class ConcreteStateB : State
{
public override void Execute(Context context)
{
Console.Write("Input state: ");
string input = Console.ReadLine();
context.State = input == "e" ? null : new ConcreteStateA();
}
}
class Context
{
private State _state;
public Context(State state)
{
State = state;
}
public State State
{
get { return _state; }
set
{
_state = value;
Console.WriteLine("State: " + _state.GetType().Name);
}
}
public void Run()
{
while (_state != null)
{
_state.Execute(this);
}
}
}
}
这实现了一个状态机,如GoF305
中所述
由于我是C#和.net的新手:是否有更好的方法使用
.net
或C#
中更具体的功能来实现这一目标?有很多方法可以应用,但主要取决于您需要完成的任务
interface IState
{
void Handle(Context context);
}
abstract class IState<T>
{
void Handle(T context);
}
Outcoldman的答案提供了许多很好的选择 现在,我知道根据模式,下面的代码不是一个合适的FSM,但是对于非常简单的实现,它可以帮助您避免编写大量额外的子类。这只是决定适合这项工作的工具的问题。这一部分主要关注
操作
通用委托的使用:
public class Context
{
public Action<Context> State { get; internal set; }
public Context(Action<Context> state)
{
State = state;
}
public void Run()
{
while (State != null)
{
State(this);
}
}
}
此外,对于不相关的状态,也可以使用Lambda表达式,例如:
Action<Context> process = context =>
{
//do something
context.State = nextContext =>
{
//something else
nextContext.State = null;
};
};
Action-process=context=>
{
//做点什么
context.State=nextContext=>
{
//别的
nextContext.State=null;
};
};
public static class SimpleStateMachine
{
public static void StateA(Context context)
{
context.State = StateB;
}
public static void StateB(Context context)
{
Console.Write("Input state: ");
var input = Console.ReadLine();
context.State = input == "e" ? (Action<Context>)null : StateA;
}
}
var context = new Context(SimpleStateMachine.StateA);
context.Run();
Console.Read();
Action<Context> process = context =>
{
//do something
context.State = nextContext =>
{
//something else
nextContext.State = null;
};
};