C# 写状态机太麻烦?试试 Stateless 库,几行代码搞定

0 阅读3分钟

前言

大家有没有遇到过这样的场景:一个对象在不同情况下行为完全不同?比如一个音乐播放器,它可能处于"停止"、"播放中"或"已暂停"状态。

在"停止"时点"暂停"应该没反应;在"播放中"点"暂停"才会真正暂停。如果用一堆 if-elseswitch 来判断当前状态再决定做什么,代码很快就会变得混乱、难维护,还容易出错。

其实,这类问题有一个经典解法——状态机(State Machine)。而在 C# 中,有一个小巧但强大的开源库叫 Stateless,能让我们用非常清晰的方式定义状态和转换规则,几乎不用写任何状态判断逻辑。

本文就带大家用一个简单例子,手把手学会如何用 C# 和 Stateless 实现一个状态机。

正文

想象我们做一个简易的播放控制模块,它有三种状态:

  • 空闲(idle):刚启动,什么都没做;

  • 运行中(running):正在播放;

  • 已暂停(paused):播放被暂停了。

用户可以触发三种操作(我们叫它"事件"):

  • 开始(start)

  • 停止(stop)

  • 暂停(pause)

这些操作在不同状态下效果不同。比如:

  • 在"空闲"时点"开始" → 进入"运行中";

  • 在"运行中"点"暂停" → 进入"已暂停";

  • 在"已暂停"时点"开始" → 回到"运行中";

  • 在"运行中"点"停止" → 回到"空闲"。

Stateless 的作用,就是让你直接声明这些规则,而不是用代码去"判断"。

完整代码

首先,通过 NuGet 安装 Stateless 库:

Install-Package Stateless

然后,编写以下 C# 代码:

namespace stateLess1
{

    public enum state
    {
        idle,
        running,
        paused,
    }
    public enum Event
    {
        start,
        stop,
        pause,
    }
    public class stateMachine1
    {
        private readonly Stateless.StateMachine<state, Event> _stateMachine;
        public stateMachine1()
        {
            _stateMachine = new Stateless.StateMachine<state, Event>(state.idle);
            _stateMachine.Configure(state.idle).Permit( Event.start,state.running);
            _stateMachine.Configure(state.running).Permit(Event.stop, state.idle)
                .Permit(Event.pause, state.paused);
            _stateMachine.Configure(state.paused).Permit(Event.start, state.running);
        }
        public void setState(Event e)
        {
            _stateMachine.Fire(e);
            Console.WriteLine($"当前状态是{_stateMachine.State}");
        }
    }
    internal class Program
    {

        static void Main(string[] args)
        {

            stateMachine1 sm = new stateMachine1();
            sm.setState(Event.start);
            sm.setState(Event.stop);
            sm.setState(Event.start);
            sm.setState(Event.pause);
        }

    }

}

代码说明

1、state 枚举:定义系统可能处于的三种状态。

2、Event 枚举:定义用户可触发的三种操作。

3、stateMachine1

在构造函数中,创建一个初始状态为 idle 的状态机。

使用 .Configure().Permit() 声明转换规则:

  • idle + startrunning

  • running + stopidle

  • running + pausepaused

  • paused + startrunning

  • setState 方法用于触发事件,并打印当前状态。

4、Main 方法

按顺序触发 start → stop → start → pause,观察状态变化。

运行结果

程序输出如下:

可以看到,状态严格按照我们设定的规则流转,没有任何非法跳转。

总结

使用 Stateless 库,我们把原本可能需要复杂条件判断的状态管理,变成了几行清晰的配置代码。

它不仅减少了 bug,还让业务逻辑一目了然。

Stateless 的优势在于:

轻量:无依赖,仅一个 DLL;

类型安全:状态和事件都用枚举定义,编译时就能发现错误;

可扩展:支持进入/退出回调、守卫条件、异步操作等高级功能。

如果你的项目中有任何"状态流转"的需求(比如订单、审批、游戏角色、设备控制),不妨试试 Stateless。它不会替你写业务,但它会帮你把状态管得明明白白。

关键词

C#、Stateless、状态机、状态管理、事件驱动、枚举、.NET、Fire、Permit、播放器示例

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

出处:mp.weixin.qq.com/s/V0_7S5MxdXZKvNvRxBrcXg

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!