You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在类内部实例化自身?请解析State类及对应设计模式

解析State类的设计:为什么内部实例化自身?这是啥模式?

好问题!咱们一步步拆解这段C#代码的设计思路、目的和对应的模式:

一、为什么要在State类内部实例化自身?

核心原因是完全控制状态实例的创建,确保类型安全和状态的唯一性:

  • 这个类的构造函数是private的,外部代码根本没法直接new State(),所有实例都只能由类自己提供。
  • 这样就能保证整个程序里只会存在你预先定义的这4个State实例,不会出现随意创建的无效状态(比如有人瞎写new State("Invalid"))。
  • 同时,每个静态属性对应的实例都是单例——首次访问时创建,之后一直复用同一个对象,避免不必要的内存开销。

二、代码逐行拆解

先贴出代码方便对照:

public class State {
    private State(String value) { 
        Value = value; 
    }
    public String Value { get; set; }
    public static State Open => new State("Open"); 
    public static State Closed => new State("Closed");
    public static State YourOpen => new State("YourOpen");
    public static State YourClosed => new State("YourClosed");
}
  • 私有构造函数:这是整个设计的关键,把实例创建权锁在类内部,外部无法随意生成State对象。
  • 静态属性(表达式体写法):public static State Open => new State("Open")这种写法是C#的语法糖,等价于一个只读的静态属性,首次访问时会创建对应的实例并缓存,之后每次访问都返回同一个对象。
  • Value属性:这里虽然是get; set;,但实际因为外部没法创建实例,只有内部的4个实例会被使用——不过更严谨的设计应该把它改成get; private set;,避免拿到实例后随意修改Value值,破坏状态的一致性。

三、这是不是用对象替代值的枚举?

没错!这就是用类实现的类型安全枚举,比C#原生的enum灵活太多:

  • 原生enum本质是整数的包装,只能关联单一的整数值;而这个State类可以轻松扩展——比如给每个状态加描述信息、添加状态转换的方法,甚至给不同状态赋予不同的行为逻辑。
  • 类型安全更强:如果你的方法参数是State类型,调用方只能传入预先定义好的4个实例,完全避免了传入无效字符串或枚举值的问题,编译器会直接帮你检查。
  • 相比字符串常量,它是强类型的——不会出现把"Open"拼写成"Oepn"这种低级错误,也不用到处写魔法字符串。

四、对应的设计模式/术语

这就是类型安全枚举模式(Type-Safe Enum Pattern),也常被简称为枚举模式(Enum Pattern)。

这个模式的核心特征就是:

  1. 私有构造函数,禁止外部创建实例;
  2. 类内部提供静态的、预定义的实例集合;
  3. 每个实例代表一个固定的状态/选项,兼具枚举的简洁性和类的扩展性。

另外,它还结合了单例模式的思想——每个静态属性对应的实例都是单例,整个程序生命周期内只会存在一个State.Open、一个State.Closed等。

和原生enum相比,这个模式最大的优势是可扩展性:比如你可以给State类添加一个CanTransitionTo(State nextState)方法,让不同的实例返回不同的结果(比如Open可以转到Closed,但Closed不能转到Open),这是原生枚举根本做不到的。

内容的提问来源于stack exchange,提问作者Mike Murphy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:23:47