创建可扩展的有限状态机

Bla*_*ear 0 c# generics state-machine

我想创建一个表示有限状态机的基类,然后由各种组件进行扩展.它应该尽可能通用,并且只允许执行专门为该机器设计的状态.这是我到目前为止所得到的:

public interface IState<out T> where T : FiniteStateMachine {
    void Enter( T p );
    void Execute( T p );
    void Exit( T p );
}

public class FiniteStateMachine {
    public IState<FiniteStateMachine> CurrentState { get; private set; }

    public void ChangeState( IState<FiniteStateMachine> s ) {
        if ( CurrentState != null )
            CurrentState.Exit( this );

        CurrentState = s;
        s.Enter( this );
    }
}

public class Car : FiniteStateMachine { }
public class Boat : FiniteStateMachine { }

public class CarState : IState<Car> {
    public void Entra( Car f ) { }
    public void Esegui( Car f ) { }
    public void Esci( Car f ) { }
}

public class BoatState : IState<Boat> {
    public void Enter( Boat f ) { }
    public void Execute( Boat f ) { }
    public void Exit( Boat f ) { }
}
Run Code Online (Sandbox Code Playgroud)

这是一个小样本:

var car = new Car( );
var boat = new Boat( );

// These are fine
car.ChangeState( new CarState( ) );
boat.ChangeState( new BoatState( ) );

// These aren't
car.ChangeState( new BoatState( ) );
boat.ChangeState( new CarState( ) );
Run Code Online (Sandbox Code Playgroud)

基本上,我只想Car.ChangeState接受实现IState<Car>,Boat.ChangeState仅接受IState<Boat>等的状态.

我无法实现这样的行为,有人可以帮助我吗?

Eri*_*ert 6

基本上,我希望Car.ChangeState只接受实现IState<Car>,Boat.ChangeState仅接受IState<Boat>等的状态.

执行此操作的典型方法是在Curiously Recurring Template模式上使用变体.我在这里描述模式的C#版本:

http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx

我建议你不要追求这个.这种模式使您的代码难以理解,并且它实际产生的限制不是您想要的限制.类型系统根本不擅长表示您想要的约束类型.类型系统不可能是所有人的所有事情.