Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图在C#中实现有限状态机,但无法转换派生类型_C#_Templates_State Machine - Fatal编程技术网

试图在C#中实现有限状态机,但无法转换派生类型

试图在C#中实现有限状态机,但无法转换派生类型,c#,templates,state-machine,C#,Templates,State Machine,我试图用一个上下文类和几个状态类实现一个最小状态机 这里有两条规则对我很重要: 上下文类不应该有关于状态类的实现(添加新的状态类不需要更改上下文类) 状态之间的转换仅在源状态上实现 以下是通用实现: public abstract class ContextState { protected State<ContextState> currentState; public void Update() { currentState.Update(

我试图用一个上下文类和几个状态类实现一个最小状态机

这里有两条规则对我很重要:

  • 上下文类不应该有关于状态类的实现(添加新的状态类不需要更改上下文类)
  • 状态之间的转换仅在源状态上实现
  • 以下是通用实现:

    public abstract class ContextState
    {
        protected State<ContextState> currentState;
        public void Update()
        {
            currentState.Update();
        }
        public void SetState(State<ContextState> state)
        {
            currentState = state;
            state.Start(this);
        }
    }
    
    public abstract class State<C> where C:ContextState
    {
        protected C context;
    
        public void Start(C context)
        {
            this.context = context;
        }
        abstract public void Update();
        abstract public void Exit();
    
        protected void SetNewState<S>() where S : State<ContextState>,new()
        {
            Exit();
            context.SetState(new S());
        }
    }
    
    公共抽象类ContextState
    {
    受保护状态当前状态;
    公共无效更新()
    {
    currentState.Update();
    }
    公共无效设置状态(状态)
    {
    当前状态=状态;
    国家。启动(本);
    }
    }
    公共抽象类状态,其中C:ContextState
    {
    受保护的C上下文;
    公共void开始(C上下文)
    {
    this.context=上下文;
    }
    抽象公共空间更新();
    抽象公共无效退出();
    受保护的void SetNewState(),其中S:State,new()
    {
    退出();
    SetState(新的S());
    }
    }
    
    现在,我尝试将这些类实现到实际应用程序中:

    public class CarConfigurationContext : ContextState
    {
        public CarConfigurationContext()
        {
            SetState(new PlayCarState());
        }
    
    }
    
    public class PlayCarState : State<CarConfigurationContext>
    {
        public override void Exit()
        {
            ...
        }
    
        public override void Update()
        {
            ...
        }
    }
    
    公共类CarConfigurationContext:ContextState { 公共CarConfigurationContext() { 设置状态(新的PlayCarState()); } } 公共类游戏机状态:状态 { 公共覆盖无效退出() { ... } 公共覆盖无效更新() { ... } } 我在
    SetState(new PlayCarState())处有一个编译错误
    无法从
    PlayCarState
    转换为
    State

    在搜索stackoverflow之后,一个可能的解决方案是使用接口而不是抽象类,但我希望将我的泛型实现保持在ContextState和State中

    如果你对我如何解决这个问题有任何想法,同时保持我的概念不变,我将不胜感激

    多谢各位

    注意:我还有一个循环引用的问题,但是因为我在C#上工作,所以我还没有考虑这个问题


    注2:通用实现尚未完成,我实际上在考虑哪些方法应该是虚拟的,在哪里应该调用Start和Exit,目前我找到的唯一解决方案是将State类的实现更改为PlayCarState:State,然后在Start方法中从ContextState动态转换为CarContextState。这在一定程度上是安全和干净的,但我想知道是否有更好的解决方案。

    对于您当前的功能,“State”可能只是“State”。不,因为我需要该State包含对ContextState的引用,但因为ContextState是一个抽象类,我需要指定来说明ContextState实现是什么。这是有意义的,因为不具有相同用途/上下文实现的状态实现不应该一起工作。