Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.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# 动态状态机的More.net方法_C#_.net_Winforms_Design Patterns_State Machine - Fatal编程技术网

C# 动态状态机的More.net方法

C# 动态状态机的More.net方法,c#,.net,winforms,design-patterns,state-machine,C#,.net,Winforms,Design Patterns,State Machine,我写了一个简单的动态FSM动态表示状态转换是动态的,而不是静态的,如ConcreteStateB所示 namespace FSM_Example { using System; class Program { static void Main() { var context = new Context(new ConcreteStateA()); context.Run();

我写了一个简单的动态FSM<代码>动态表示状态转换是动态的,而不是静态的,如
ConcreteStateB
所示

namespace FSM_Example
{
    using System;

    class Program
    {
        static void Main()
        {
            var context = new Context(new ConcreteStateA());
            context.Run();
            Console.Read();
        }
    }

    abstract class State
    {
        public abstract void Execute(Context context);
    }

    class ConcreteStateA : State
    {
        public override void Execute(Context context)
        {
            context.State = new ConcreteStateB();
        }
    }

    class ConcreteStateB : State
    {
        public override void Execute(Context context)
        {
            Console.Write("Input state: ");
            string input = Console.ReadLine();
            context.State = input == "e" ? null : new ConcreteStateA();
        }
    }

    class Context
    {
        private State _state;

        public Context(State state)
        {
            State = state;
        }

        public State State
        {
            get { return _state; }
            set
            {
                _state = value;
                Console.WriteLine("State: " + _state.GetType().Name);
            }
        }

        public void Run()
        {
            while (_state != null)
            {
                _state.Execute(this);
            }
        }
    }
}
这实现了一个状态机,如
GoF305
中所述


由于我是C#和.net的新手:是否有更好的方法使用
.net
C#
中更具体的功能来实现这一目标?

有很多方法可以应用,但主要取决于您需要完成的任务

  • 您可以使用接口而不是抽象类。在C#中,您不能继承多个类,因此最好不要从实现中使用此选项

    interface IState
    {
         void Handle(Context context);
    }
    
  • 您可以使用泛型,因此您可以为状态模式编写一次基本接口/类,并在任何地方使用它:

    abstract class IState<T>
    {
         void Handle(T context);
    }
    
  • 我打赌已经有人用


  • Outcoldman的答案提供了许多很好的选择

    现在,我知道根据模式,下面的代码不是一个合适的FSM,但是对于非常简单的实现,它可以帮助您避免编写大量额外的子类。这只是决定适合这项工作的工具的问题。这一部分主要关注
    操作
    通用委托的使用:

    public class Context
    {
        public Action<Context> State { get; internal set; }
    
        public Context(Action<Context> state)
        {
            State = state;
        }
    
        public void Run()
        {
            while (State != null)
            {
                State(this);
            }
        }
    }
    
    此外,对于不相关的状态,也可以使用Lambda表达式,例如:

    Action<Context> process = context =>
        {
            //do something
            context.State = nextContext =>
                {
                    //something else
                    nextContext.State = null;
                };
        };
    
    Action-process=context=>
    {
    //做点什么
    context.State=nextContext=>
    {
    //别的
    nextContext.State=null;
    };
    };
    
    public static class SimpleStateMachine
    {
        public static void StateA(Context context)
        {
            context.State = StateB;
        }
        public static void StateB(Context context)
        {
            Console.Write("Input state: ");
            var input = Console.ReadLine();
            context.State = input == "e" ? (Action<Context>)null : StateA;
        }
    }
    
    var context = new Context(SimpleStateMachine.StateA);
    context.Run();
    Console.Read();
    
    Action<Context> process = context =>
        {
            //do something
            context.State = nextContext =>
                {
                    //something else
                    nextContext.State = null;
                };
        };