IDisposable的另类用法
目录
IDisposable是.Net中一个很重要的接口,一般用来释放非托管资源,我们知道在使用了IDisposable的对象之后一定要调用IDisposable.Dispose()方法,或者使用.Net提供的关键字using来达到这一目的,如:
1 2 3 4 5 6 7 8 | public void ReadFile() { using ( var reader= new StreamReader( "c:\\test.txt" )) { var text= reader.ReadToEnd(); Console.WriteLine(text); } } |
使用using关键字后,编译器将在他的末尾自动插入一个Dispose方法的调用。我们可以利用这一点尝试完成下面的需求:
我们希望将警告的文本以红色显示在控制台上,然后再恢复初始颜色显示其他文本内容。按照传统做法,我们先存储初始颜色,设定新颜色,向控制台输出警告信息,恢复初始颜色,输出其他文本。
1 2 3 4 5 6 7 8 9 10 11 | public void Show() { var originalColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine( "dangerous message" ); Console.ForegroundColor = originalColor; Console.WriteLine( "other message" ); } |
如果利用我们前面分析的IDisposable模式,我们先实现一个能够接收Action类型的通用Disposable:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class DisposableAction:IDisposable { private readonly Action _action; public DisposableAction(Action action) { _action = action; } public void Dispose() { _action(); } } |
进一步实现之前的需求
1 2 3 4 5 6 7 8 9 10 11 12 | public void Show() { var originalColor = Console.ForegroundColor; using ( new DisposableAction(()=>Console.ForegroundColor=originalColor)) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine( "dangerous message" ); } Console.WriteLine( "other message" ); } |
这似乎也没比上面高明多少,是因为这个例子不能够展现这个模式的威力。在《三种观察者模式的C#实现》一文中,我介绍的第三种方案是利用Action来实现,而该文并没有给出如何取消订阅的方法。利用本文的内容将会实现一个优雅的取消订阅方案:
1 2 3 4 5 6 | public IDisposable OnAlarm(Action<AlarmData> alarmAction) { _alarmActions.Add(alarmAction); return new DisposedAction(()=>_alarmActions.Remove(alarmAction)); } |
如果想只订阅一次,就使用using:
1 2 3 4 | using (_clock.OnAlarm(data => { /*alarm*/ })) { } |
反之,如果不想取消订阅就不要使用using,不要调用Dispose()方法。
作者:Richie Zhang
声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?