[英]Local instance of a base enum or passing enum collection?
我使用Stateless在多个类中实现FSM。 ( http://code.google.com/p/stateless/ )
我想使用基类来触发触发器和日志记录等。我还想强制继承我的baseFSM类的任何类都使用它们自己的本地状态和触发器来实现StateMachine。
但是我的问题是,枚举不能被抽象或传递给函数。
顺便说一句,Stateless说“通用支持任何.NET类型的状态和触发器(数字,字符串,枚举等)”,所以如果有更好的方法可以解决这个问题,请告诉我。
理想情况下,这是我想要实现的(或者可以以相同的方式工作的东西)。
BaseFSM类:
public abstract class BaseFSM : IStateMachine
{
#region Implementation of IStateMachine
public ICall LocalCall { get; set; }
#endregion
internal abstract enum State {}
internal abstract enum Trigger {}
internal abstract StateMachine<State, Trigger> fsm { get; set; }
public abstract void Fire(Enum trigger);
}
实现BaseFSM的类:
class Incoming_Initial : BaseFSM
{
private enum State
{
WaitForCallToBeAnswered,
CallConnected,
CallNeverConnected,
CheckForCustomIntro,
PlayIntro,
PlayPleaseEnterPin,
ReadLanguageSettings,
ChooseLanguage,
ValidatePIN,
PINWasInvalid,
IdentifyUser
}
private enum Trigger
{
Yes,
No,
DigitPressed,
PromptDonePlaying,
PromptTimerElapse,
Done
}
public Incoming_Initial(ICall call)
{
LocalCall = call;
fsm = new StateMachine<this.State, this.Trigger>(State.WaitForCallToBeAnswered);
....
或者我甚至会采取这样的事情:
public class myStateMachine
{
private enum State{}
private enum Trigger{}
private StateMachine<State, Trigger> stateMachine;
public myStateMachine (Enum _states, Enum _triggers, Enum _startState)
{
State = _states;
Trigger = _triggers;
stateMachine = new StateMachine<State, Trigger>(_startState);
}
}
任何关于我如何实现这一点的见解将不胜感激!
编辑 :我的最终目标是使用Stateless来实现具有~40种不同FSM的IVR( IVR )系统。 状态机将负责呼叫流程以及用户与系统的交互方式。 我已经有一个演示状态机工作,但状态和触发器是该类的本地。
我只是想看看我是否可以将状态机拉出到基类,所以我不必将状态机传递给辅助函数。
如果我可以将状态机放在基类中,我想我可以使用一组触发器(这些是来自电话呼叫的事件,如CallConnected,UserPressedDigit,CallDisconnected,PromptDonePlaying等),只需为每个FSM实现状态。
答案(至少我如何使用这个)感谢@phoog:
public abstract class BaseFSM <TState> : IStateMachine
{
#region Implementation of IStateMachine
public ICall LocalCall { get; set; }
#endregion
public enum Triggers
{
Yes = 0,
No,
DigitPressed,
PromptDonePlaying,
PromptTimerElapse,
Done
}
protected IList<TState> States { get; set; }
protected StateMachine<TState, Triggers> fsm { get; set; }
...
class Incoming_Initial : BaseFSM<Incoming_Initial.State>
{
internal enum State
{
WaitForCallToBeAnswered,
CallConnected,
CallNeverConnected,
CheckForCustomIntro,
PlayIntro,
PlayPleaseEnterPin,
ReadLanguageSettings,
ChooseLanguage,
ValidatePIN,
PINWasInvalid,
IdentifyUser
}
public Incoming_Initial(ICall call)
{
LocalCall = call;
LocalCall.CallEventHandler += new CallEventHandler(LocalCall_CallEventHandler);
States = (State[]) Enum.GetValues(typeof (State));
fsm = new StateMachine<State, Triggers>(State.WaitForCallToBeAnswered);
请注意, Enum
类型表示对Enum
的盒装值的引用; 它没有引用整个枚举类型。 因此,例如,此代码有效:
enum Something { Value0, Value1, Value2, Value3 }
void ProcessAnEnumValue(Enum value)
{
//...whatever
}
void CallTheMethod()
{
ProcessAnEnumValue(Something.Value2);
}
您正在尝试参数化整个枚举类型; 参数化类型的工具是泛型。 考虑到这一点,您的代码可以使用一些修改:
public abstract class BaseFSM<TState, TTrigger> : IStateMachine
{
#region Implementation of IStateMachine
public ICall LocalCall { get; set; }
#endregion
protected IList<TState> States { get; set; }
protected IList<TTrigger> Triggers { get; set; }
protected StateMachine<TState, TTrigger> fsm { get; set; }
public abstract void Fire(TTrigger trigger);
}
class Incoming_Initial : BaseFSM<Incoming_Initial.State, Incoming_Initial.Trigger>
{
public enum State
{
WaitForCallToBeAnswered,
CallConnected,
CallNeverConnected,
CheckForCustomIntro,
PlayIntro,
PlayPleaseEnterPin,
ReadLanguageSettings,
ChooseLanguage,
ValidatePIN,
PINWasInvalid,
IdentifyUser
}
public enum Trigger
{
Yes,
No,
DigitPressed,
PromptDonePlaying,
PromptTimerElapse,
Done
}
public Incoming_Initial(ICall call)
{
States = (State[])Enum.GetValues(typeof(State));
Triggers = (Trigger[])Enum.GetValues(typeof(Trigger));
LocalCall = call;
fsm = new StateMachine<State, Trigger>(State.WaitForCallToBeAnswered);
....
你不能用枚举,
对于不同的枚举没有“基类” (内部有,对于ValueType-s等,但是你不能使用它 - 枚举。有方法来处理枚举GetValues等但是那就是这样)。
如果我是你,我会让你的'枚举'真的成为单独的类,所以每个状态和事件/触发器都有自己的表示类 - 并给它们所有可以共享的基类(我的意思是一个用于触发器的状态) )。
然后你也可以使用一些状态机模式来浏览状态,并在它们之间切换。
或者根据您可能拥有的内容,您可能希望使用访问者(如果您有更复杂的层次结构等)来处理事物等(但这是针对更复杂的情况并组合不同的模式,这通常是必要的)。
很难说,缺少一些细节,你想用它做什么,目标等大图,有很多方法。
免责声明:不熟悉您所指的“无国籍”,也可能采用其他方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.