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

如何基于C#枚举为LicenseState类实现对应构造方法?

实现方案与优化建议

基础实现:重载构造并添加合法性校验

通过重载构造方法,并在构造内部校验参数的合法性,确保不同状态使用对应的构造逻辑:

public enum LicenseStateType
{
    Valid,
    Expiring,
    Expired
}

public class LicenseState
{
    public LicenseStateType State { get; protected set; }
    public int DaysLeft { get; protected set; }

    // 仅用于Valid/Expired状态的构造
    public LicenseState(LicenseStateType type)
    {
        if (type is not (LicenseStateType.Valid or LicenseStateType.Expired))
        {
            throw new ArgumentException($"此构造仅支持{nameof(LicenseStateType.Valid)}或{nameof(LicenseStateType.Expired)}状态", nameof(type));
        }
        State = type;
        DaysLeft = 0; // 非预警状态下剩余天数设为0,可根据需求调整
    }

    // 仅用于Expiring状态的构造
    public LicenseState(LicenseStateType type, int daysLeft)
    {
        if (type != LicenseStateType.Expiring)
        {
            throw new ArgumentException($"此构造仅支持{nameof(LicenseStateType.Expiring)}状态", nameof(type));
        }
        if (daysLeft <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(daysLeft), "剩余天数必须大于0");
        }
        State = type;
        DaysLeft = daysLeft;
    }
}

这种方式直接满足需求,但调用方需要准确记住不同状态对应的构造方法,存在误用的可能性。

更优方案:静态工厂方法

使用语义化的静态工厂方法封装实例创建逻辑,让调用更直观、安全,避免参数组合错误:

public enum LicenseStateType
{
    Valid,
    Expiring,
    Expired
}

public class LicenseState
{
    public LicenseStateType State { get; }
    public int DaysLeft { get; }

    // 私有构造,强制所有实例通过工厂方法创建
    private LicenseState(LicenseStateType state, int daysLeft)
    {
        State = state;
        DaysLeft = daysLeft;
    }

    public static LicenseState CreateValid()
    {
        return new LicenseState(LicenseStateType.Valid, 0);
    }

    public static LicenseState CreateExpired()
    {
        return new LicenseState(LicenseStateType.Expired, 0);
    }

    public static LicenseState CreateExpiring(int daysLeft)
    {
        if (daysLeft <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(daysLeft), "剩余天数必须大于0");
        }
        return new LicenseState(LicenseStateType.Expiring, daysLeft);
    }
}

方案优势:

  • 调用直观:调用方无需关注构造参数,通过CreateValid()、CreateExpired()、CreateExpiring(int)等语义化方法直接创建对应状态的实例,降低学习成本和误用概率
  • 逻辑集中:所有状态创建的校验和规则都封装在工厂方法中,便于统一维护
  • 扩展性强:后续新增状态或调整创建规则时,只需添加或修改工厂方法,无需修改构造逻辑

进阶扩展:状态模式(若需状态相关行为)

如果未来需要为不同许可证状态添加专属行为(比如不同状态下的验证逻辑、提示文案生成等),可以采用状态模式,为每个状态创建子类:

public abstract class LicenseState
{
    public abstract LicenseStateType State { get; }
    public virtual int DaysLeft => 0;

    // 示例:状态专属行为
    public abstract string GetStatusMessage();
}

public class ValidLicenseState : LicenseState
{
    public override LicenseStateType State => LicenseStateType.Valid;
    public override string GetStatusMessage() => "许可证状态有效";
}

public class ExpiredLicenseState : LicenseState
{
    public override LicenseStateType State => LicenseStateType.Expired;
    public override string GetStatusMessage() => "许可证已过期";
}

public class ExpiringLicenseState : LicenseState
{
    public override LicenseStateType State => LicenseStateType.Expiring;
    public override int DaysLeft { get; }

    public ExpiringLicenseState(int daysLeft)
    {
        if (daysLeft <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(daysLeft), "剩余天数必须大于0");
        }
        DaysLeft = daysLeft;
    }

    public override string GetStatusMessage() => $"许可证将在{DaysLeft}天后过期";
}

这种方式将状态与行为绑定,适合状态需要承载业务逻辑的场景,代码的可读性和扩展性更强。

内容的提问来源于stack exchange,提问作者Antonio Argentieri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:17:25