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

寻求类似IDisposable(及using语句)的设计模式方案

解决方案:借助IDisposable实现自动调用End

1. 改造原类,新增辅助Disposable类型

修改你的Foo类,在内部定义一个实现IDisposable的私有嵌套类,让它持有外部Foo实例的引用,并在Dispose方法中调用End。同时调整Start方法,返回这个辅助对象:

public class Foo
{
    private bool _isStarted = false;

    public IDisposable Start()
    {
        if (_isStarted)
            throw new InvalidOperationException("已经调用过Start方法");
        
        // 执行原Start的业务逻辑
        Console.WriteLine("启动资源");
        _isStarted = true;

        return new FooDisposable(this);
    }

    public void End()
    {
        if (!_isStarted)
            throw new InvalidOperationException("未调用Start方法,无法执行End");
        
        // 执行原End的清理逻辑
        Console.WriteLine("释放资源");
        _isStarted = false;
    }

    private class FooDisposable : IDisposable
    {
        private readonly Foo _foo;
        private bool _disposed = false;

        public FooDisposable(Foo foo)
        {
            _foo = foo;
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _foo.End();
                _disposed = true;
            }
        }
    }
}

2. 使用方式

现在开发者可以直接用using语句,完全符合你期望的写法,无需手动调用End:

using (var foo = new Foo())
using (foo.Start())
{
    // 执行核心业务逻辑
    Console.WriteLine("处理业务内容");
}
// 作用域结束后,自动触发Foo.End()

也可以用C# 8.0+的简化写法:

using var foo = new Foo();
using (foo.Start())
{
    // 业务逻辑
}

3. 额外防护机制

  • 增加_isStarted状态标记,避免重复调用Start或未启动就执行End,防止逻辑混乱。
  • 辅助类的Dispose方法加入重复调用防护,即使手动多次调用Dispose,也不会重复执行End。

方案优势

  • 强制约束:开发者只要遵循using的使用规范,就必然触发End,彻底避免遗忘调用的问题。
  • 语义清晰:using本身就带有“自动清理资源”的语义,符合C#开发者的使用习惯,可读性强。
  • 封装性好:End的调用逻辑被封装在内部,外部不需要关心实现细节,只需要专注业务代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 18:22:07