IDisposable是.Net中一个很重要的接口,一般用来释放非托管资源,我们知道在使用了IDisposable的对象之后一定要调用IDisposable.Dispose()方法,或者使用.Net提供的关键字using来达到这一目的,如:

        public void ReadFile()
{
using (var reader=new StreamReader("c:\\test.txt"))
{
var text= reader.ReadToEnd();
Console.WriteLine(text);
}
}

使用using关键字后,编译器将在他的末尾自动插入一个Dispose方法的调用。我们可以利用这一点尝试完成下面的需求:

我们希望将警告的文本以红色显示在控制台上,然后再恢复初始颜色显示其他文本内容。按照传统做法,我们先存储初始颜色,设定新颜色,向控制台输出警告信息,恢复初始颜色,输出其他文本。

        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:

    public class DisposableAction:IDisposable
{
private readonly Action _action; public DisposableAction(Action action)
{
_action = action;
} public void Dispose()
{
_action();
}
}

进一步实现之前的需求

       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来实现,而该文并没有给出如何取消订阅的方法。利用本文的内容将会实现一个优雅的取消订阅方案:

       public IDisposable OnAlarm(Action<AlarmData> alarmAction)
{
_alarmActions.Add(alarmAction); return new DisposedAction(()=>_alarmActions.Remove(alarmAction));
}

如果想只订阅一次,就使用using:

 using (_clock.OnAlarm(data => {/*alarm*/ }))
{ }

反之,如果不想取消订阅就不要使用using,不要调用Dispose()方法。

IDisposable的另类用法的更多相关文章

  1. 研究 Javascript的&&和||的另类用法

    这篇文章主要介绍了Javascript的&&和||的另类用法,需要的朋友可以参考下 最近也没什么心思写文章了,感觉总有忙不完的事情,呵. 不过这些天又开始研究起 Titanium 来, ...

  2. Python装饰器的另类用法

    之前有比较系统介绍过Python的装饰器(请查阅<详解Python装饰器>),本文算是一个补充.今天我们一起探讨一下装饰器的另类用法. 语法回顾 开始之前我们再将Python装饰器的语法回 ...

  3. Javascript的&&和||的另类用法

    Javascript的&&和||的另类用法. 又开始研究起 Titanium 来,发现其官方出品的MVC框架(Alloy)还是挺不错的,刚开始苦于没有好的代码来学习,文档又少,所以一直 ...

  4. 写在Github被微软收购之际 - Github的那些另类用法

    这几天朋友圈被微软75亿美元收购Github的新闻刷屏了.Jerry也来贡献一篇和Github相关的文章. 这篇文章包含了Jerry平时对于Github的一些另类用法.目录如下: 1. 部署HTML应 ...

  5. Rpm另类用法加固Linux安全

    Rpm另类用法加固Linux安全   RPM是Red Hat Package Manager的缩写即Red Hat软件管理器.它是一个开放的包管理软件,由Red Hat公司所开发和维护,可以在Red ...

  6. 删除重复信息且要保留一条的(roacle的rowid另类用法)

    由于表的主键失效了(disable),导致导入了一些主键重复的数据,想保留唯一的一条, 最后发现其实可以用rowid来实现,不知道算不算是rowid的另类用法. delete /*+ parallel ...

  7. CSS ::before 和 ::after 伪元素另类用法

    原文地址:http://justcoding.iteye.com/blog/2032627 CSS 有两个说不上常用的伪类 :before 和 :after,偶尔会被人用来添加些自定义格式什么的,但是 ...

  8. react.js 生命周期componentDidUpdate的另类用法:防止页面过渡刷新

    场景:数据新增成功之后,需要返回原来的查询表,这时候的查询,需要使用react的生命周期:componentDidUpdate componentDidUpdate() 这个生命周期的作用是当prop ...

  9. 渗透中Necat的另类用法

    Necat 是一个伟大而实用的用于 TCP 和 UPD 网络连接协议的读写程序.同时 Necat 也被誉为网络中的瑞士军刀,在许多黑客教程中 Necat 也被广泛使用.Necat 最常见用途是设置反向 ...

随机推荐

  1. Redis五种数据类型命令介绍(4)

    1.string类型命令 设置值:set id 001 获取值:get id  删除键值:del id  验证键是否存在:exists id 显示所有的key:keys * incr .incrby指 ...

  2. 【Java EE 学习 74 下】【数据采集系统第六天】【使用Jfreechart的统计图实现】【将JFreechart整合到项目中】

    之前说了JFreechart的基本使用方法,包括生成饼图.柱状统计图和折线统计图的方法.现在需要将其整合到数据采集系统中根据调查结果生成三种不同的统计图. 一.统计模型的分析和设计 实现统计图显示的流 ...

  3. C#使用ListView更新数据出现闪烁解决办法

    C#使用ListView更新数据出现闪烁解决办法 在使用vs自动控件ListView控件时候,更新里面的部分代码时候出现闪烁的情况 如图: 解决以后: 解决办法使用双缓冲:添加新类继承ListView ...

  4. SVN使用教程之-分支/标记 合并 subeclipse (转)

    首先说下为什么我们需要用到分支-合 并.比如项目demo下有两个小组,svn下有一个trunk版.由于客户需求突然变化,导致项目需要做较大改动,此时项目组决定由小组1继续完成原来正 进行到一半的工作[ ...

  5. pyqt的信号槽机制(转)

    PySide/PyQt Tutorial: Creating Your Own Signals and Slots This article is part 5 of 8 in the series  ...

  6. c#程序中对密码进行加密的方法

    在ADO.NET中,向数据库添加数据时,怎样对数据中的密码进行加密?(也就是说在数据表中也看不到用户的密 码,只是一些经过编译后的字符串,以防止数据库管理员利用用户的密码进行非法操作.)    首先, ...

  7. 《DSP using MATLAB》示例Example5.18

  8. OSG消息机制之消息分析

    OSG消息接收在头文件有各种事件的相关参数

  9. 《程序员的自我修养》读书笔记 - dllimport

    Math.c  { __declspec (dllexport)  double Add (xx, xx) {...}} MathApp.c  { __declspec(dllimport) doub ...

  10. gradle下载地址

    gradle下载:http://services.gradle.org/distributions