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

C#状态模式中ChangeState方法私有可见性的实现疑问

C#状态模式:隐藏状态切换接口的实现方案

问题背景

我正在实现状态模式,状态类需要修改Context的状态,但要求ChangeState方法仅对状态类可见,不能暴露给客户端。我尝试用接口分离,但不知道如何在对外暴露的Context类中实现私有接口供状态类使用。

以下是我的初步代码:

对外暴露的Context接口与类

public interface IContext 
{
    string Input { get; set; }
    void DoTransition();
}

public class Context : IContext
{ 
    public string Input { get; set; }

    private AbstractState _state;

    public void DoTransition() 
    {
        _state.DoTransition();
    }
}

状态切换接口(需隐藏)

public interface IChangeState 
{
    void ChangeState(IState state);
}

状态类实现

public interface IState 
{
    void DoTransition();
}

public abstract class AbstractState : IState 
{
    private IChangeState _stateChanger;

    public AbstractState(IChangeState stateChanger) => _stateChanger = stateChanger;

    public virtual void DoTransition() 
    {
        _stateChanger.ChangeState(new NextState(_stateChanger));
    }
}

public class NextState : AbstractState 
{
    public NextState(IChangeState stateChanger) 
        : base(stateChanger)
    { }

    public override void DoTransition()
    {
        base.DoTransition();
    }
}

解决方案

在C#中可以通过显式接口实现来隐藏IChangeState的方法,这样客户端通过IContext接口无法访问ChangeState,只有状态类持有IChangeState引用时才能调用。

修改后的完整代码如下:

调整后的Context类(显式实现IChangeState)

public interface IContext 
{
    string Input { get; set; }
    void DoTransition();
}

public interface IChangeState 
{
    void ChangeState(IState state);
}

public class Context : IContext, IChangeState
{ 
    public string Input { get; set; }

    private AbstractState _state;

    // 构造函数初始化初始状态,将自身作为IChangeState传入
    public Context()
    {
        _state = new InitialState(this);
    }

    public void DoTransition() 
    {
        _state.DoTransition();
    }

    // 显式实现IChangeState,对外不可见
    void IChangeState.ChangeState(IState state)
    {
        if (state is AbstractState abstractState)
        {
            _state = abstractState;
        }
    }
}

状态类保持不变(可按需扩展)

public interface IState 
{
    void DoTransition();
}

public abstract class AbstractState : IState 
{
    protected IChangeState StateChanger { get; }

    public AbstractState(IChangeState stateChanger) 
    {
        StateChanger = stateChanger;
    }

    public virtual void DoTransition() 
    {
        // 示例:切换到下一个状态
        StateChanger.ChangeState(new NextState(StateChanger));
    }
}

public class InitialState : AbstractState
{
    public InitialState(IChangeState stateChanger) : base(stateChanger) { }

    public override void DoTransition()
    {
        // 初始状态的切换逻辑
        StateChanger.ChangeState(new NextState(StateChanger));
    }
}

public class NextState : AbstractState 
{
    public NextState(IChangeState stateChanger) : base(stateChanger) { }

    public override void DoTransition()
    {
        // 下一个状态的切换逻辑,比如切换回初始状态
        StateChanger.ChangeState(new InitialState(StateChanger));
    }
}

关键说明

  • 显式接口实现:void IChangeState.ChangeState(...)这种写法让方法只能通过IChangeState类型的引用访问,客户端拿到IContext实例时看不到这个方法。
  • 状态类依赖IChangeState:状态类通过构造函数注入IChangeState,仅能调用状态切换方法,无法访问Context的其他公开成员,符合单一职责原则。
  • 客户端使用方式:客户端仅需依赖IContext接口,完全感知不到IChangeState的存在:
// 客户端代码
IContext context = new Context();
context.Input = "test";
context.DoTransition();
// 此处无法调用ChangeState方法,因为IContext中未定义

内容的提问来源于stack exchange,提问作者Felix Arnold

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:18:20