寻求类似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
相关产品推荐
相关产品推荐

