私はFSMを複数のクラスに実装するためにステートレスを使用しています。 (http://code.google.com/p/stateless/)ベースenumまたはenumコレクションを渡すローカルインスタンス?
私は は、私はまた、任意のクラスを継承私baseFSMクラスは独自のローカル米国およびトリガとステートマシンを実装することを強制したい...トリガーやログなどを発射するための基本クラスを使用します。
しかし私の問題は、列挙型を抽象化したり関数に渡すことができないことです。
ところで、ステートレスは「どの.NETタイプ(数値、文字列、列挙型など)の状態とトリガも一般的にサポートしています」と言っています。
理想的には、これは私が実装したいもの(または同じように動作するもの)です。
BaseFSMクラス: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);
}
クラス:
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);
....
OR私もこのような何かを取る:
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);
}
}
私は行くことができる方法上の任意の洞察力これを実装することについて大いに感謝します!
編集:究極の目標は、ステートレスを使用して〜40の異なるFSMを持つIVR(IVR)システムを実装することです。ステートマシンは、コールフローとユーザーがシステムとやりとりする方法を担当します。デモ状態マシンはすでに動作していますが、ステートとトリガーはそのクラスのローカルです。
ステートマシンを基本クラスにプルできるかどうかを確認しようとしているので、ステートマシンをヘルパ関数に渡す必要はありません。
状態マシンを基本クラスに置くことができるのであれば、私はTriggers(CallConnected、UserPressedDigit、CallDisconnected、PromptDonePlayingなどのような電話からのイベント)を使用でき、各FSMの状態。
ANSWER(私はこれを使用しています少なくともどのように)@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);
これは非常に素晴らしい!どうもありがとうございました! – jpiccolo
これは彼が必要としていることに対する良い答えです!しかし、Enumはジェネリックに厳密な型や制約を与えていません。オブジェクトを使うこともできますし、大きな違いを感じることもありません。 Btw。ジェネリックスを以下のように制約する必要があります:struct少なくとも(それは可能です)。 – NSGaga
@NSGagaもちろん、あなたは正しいです。彼らは必要ないように私は制約を加えなかった。列挙型ではない型を使用した場合、基本クラスには何もありません。 Jon Skeetには "unconstrained melody"というプロジェクトがあり、ILを書き換えることで列挙制約を適用できます.CLRは列挙制約をサポートしていますが、C#だけはそうではありません。 – phoog