大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C#技巧 > Lambda表达式实现有限状态机

Lambda表达式实现有限状态机

关键词:Lambda有限状态机  阅读(1959) 赞(16)

[摘要]本文是对Lambda表达式实现有限状态机的讲解,对学习C#编程技术有所帮助,与大家分享。

实现状态机有多种模式,其中最灵活而强大的方式是通过迁移表来实现,该方式的缺点之一是需要编写大量小块代码去支持迁移表。而在C#3.0中,可以以一种非常优雅的方式实现。
除了有限状态机外,还有有限自动机,有限自动机一般用于分析字符。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;

namespaceStateMachine
{
classProgram
{
staticvoidMain(string[] args)
{
vardoor =newDoor(State.Open);

while(true)
{
strings =Console.ReadLine();
Operationop =string.IsNullOrEmpty(s) ?Operation.Push :Operation.Pull;
door.Process(op);
}
}
}

enumOperation
{
Push, Pull
}

enumState
{
Open, Closed
}

classDoor
{
publicStateState {get;set; }

Dictionary<State,Dictionary<Operation,Action>> rule;
publicDoor(Statestate)
{
this.State = state;

rule =newDictionary<State,Dictionary<Operation,Action>>();
foreach(vareinEnum.GetValues(typeof(State)))
{
rule[(State)e] =newDictionary<Operation,Action>();
}

InitOperationRule();
}

voidInitOperationRule()
{
//正常操作
rule[State.Closed][Operation.Push] = () => {Console.WriteLine("门被推开了"); State =State.Open; };
rule[State.Open][Operation.Pull] = () => {Console.WriteLine("门被拉上了"); State =State.Closed; };

////加入几种特殊情况的处理
//rule[State.Closed][Operation.Pull] = () => Console.WriteLine("门是关上的,拉了也白拉");
//rule[State.Open][Operation.Push] = () => Console.WriteLine("门是开的,不用推了,直接进去吧");
}

publicvoidProcess(Operationop)
{
try
{
rule[State][op]();
}
catch(KeyNotFoundException)
{

Console.WriteLine(string.Format("门在{0}状态下不允许{1}操作", State, op));
}

}
}
}

从代码中可以看到,通过lambda表达式,可以简化迁移表的构造,并且更加直观。
通过迁移表构造状态机的一种不足在于查询速度,在本例中每个操作都要进行两次查询才能进行状态转换操作。如果状态较多则非常费时,这里我把它改进了一下,使得每次操作只需要查询一次即可。

classDoorPlus
{
Statestate;
publicStateState
{
get{returnstate; }
set
{
if(state !=value)
currentOpRule = rule[value];
state =value;
}
}

Dictionary<Operation,Action> currentOpRule;
Dictionary<State,Dictionary<Operation,Action>> rule;
publicDoorPlus(Statestate)
{
this.State = state;

rule =newDictionary<State,Dictionary<Operation,Action>>();
foreach(vareinEnum.GetValues(typeof(State)))
{
rule[(State)e] =newDictionary<Operation,Action>();
}

currentOpRule = rule[State];

InitOperationRule();
}

voidInitOperationRule()
{
//正常操作
rule[State.Closed][Operation.Push] = () => {Console.WriteLine("门被推开了"); State =State.Open; };
rule[State.Open][Operation.Pull] = () => {Console.WriteLine("门被拉上了"); State =State.Closed; };

////加入几种特殊情况的处理
//rule[State.Closed][Operation.Pull] = () => Console.WriteLine("门是关上的,拉了也白拉");
//rule[State.Open][Operation.Push] = () => Console.WriteLine("门是开的,不用推了,直接进去吧");
}

publicvoidProcess(Operationop)
{
try
{
currentOpRule[op]();
}
catch(KeyNotFoundException)
{

Console.WriteLine(string.Format("门在{0}状态下不允许{1}操作", State, op));
}
}
}



相关评论