Mat*_*ren 25 c# yield state-machine fsm
使用yield关键字来实现这里所示的简单状态机是否可行.对我来说,看起来C#编译器为您完成了艰苦的工作,因为它在内部实现了状态机以使yield语句有效.
你可以在编译器已经完成的工作之上捎带并让它为你实现大部分状态机吗?
有没有人这样做,技术上可行吗?
Eri*_*ert 49
这是可行的,但这是一个坏主意.创建迭代器块是为了帮助您为集合编写自定义迭代器,而不是为了解决实现状态机的通用问题.
如果要编写状态机,只需编写状态机即可.这并不难.如果要编写大量状态机,请编写一个有用的辅助方法库,使您可以干净地表示状态机,然后使用您的库.但是,不要滥用意图完全不同的语言结构,而恰好使用状态机作为实现细节.这使您的状态机代码难以阅读,理解,调试,维护和扩展.
(顺便说一句,我在读你的名字时做了一个双重考虑.其中一位C#的设计师也被命名为马特沃伦!)
是的,这绝对可行且容易做到.您可以尽情使用控制流结构(for,foreach,while,... goto(使用goto特别适合这个场景;)))连同yields到建立一个.
IEnumerator<State> StateMachine
(Func<int> currentInput /* gets current input from IO port */,
Func<int> currentOutput) {
for (;;) {
if ((currentInput() & 1) == 0)
yield return new State("Ready");
else {
if (...) {
yield return new State("Expecting more data");
SendOutput(currentOutput());
while ((currentInput() & 2) != 0) // while device busy
yield return new State("Busy");
else if (...) { ... }
}
}
}
// consumer:
int data;
var fsm = StateMachine(ReadFromIOPort, () => data);
// ...
while (fsm.Current != "Expecting more data")
fsm.MoveNext();
data = 100;
fsm.MoveNext();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10617 次 |
| 最近记录: |