编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源
2015-08-16 15:42
507 查看
建议50:在Dispose模式中应区别对待托管资源和非托管资源
真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源。
提供给调用者调用的显式释放资源的无参Dispose方法中,调用参数是true:
这表明,这时候代码要同时处理托管资源和非托管资源。
在供垃圾回收器调用的隐式清理资源的终结器中,调用的是false:
这表明,隐式清理时,只要处理非托管资源就可以了。
为什么要区别对待托管资源和非托管资源呢?在这个问题前,我们首先要弄明白:托管资源需要手工清理吗?不妨将C#中的类型分为两类,一类继承了IDisposable接口,一类则没有继承。前者,暂时称为非普通类型,后者称为普通类型。非普通类型因为包含非托管资源,所以它需要继承IDisposable接口,但是,这里包含非托管资源的类型本身,它是一个托管资源。所以,托管资源中的普通类型不需要手动清理,而非普通类型是需要手工清理的(即调用Dispose方法)。
Dispose模式设计的思路是:如果调用者显式调用了Dispose方法,那么类型就应该按部就班地将自己的资源全部释放。如果调用者忘记调用Dispose方法,那么类型就假设自己的所有托管资源(哪怕是那些非普通类型)会全部都交给垃圾回收器回收,所以不进行手工清理。所以在Dispose方法中,虚方法传入参数true,在终结器中,虚方法传入参数false。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
真正资源释放代码的那个虚方法是带一个bool参数的,带这个参数,是因为我们在资源释放时要区别对待托管资源和非托管资源。
提供给调用者调用的显式释放资源的无参Dispose方法中,调用参数是true:
public void Dispose() { //必须为true Dispose(true); //省略其他代码 }
这表明,这时候代码要同时处理托管资源和非托管资源。
在供垃圾回收器调用的隐式清理资源的终结器中,调用的是false:
~SampleClass() { //必须为false Dispose(false); }
这表明,隐式清理时,只要处理非托管资源就可以了。
为什么要区别对待托管资源和非托管资源呢?在这个问题前,我们首先要弄明白:托管资源需要手工清理吗?不妨将C#中的类型分为两类,一类继承了IDisposable接口,一类则没有继承。前者,暂时称为非普通类型,后者称为普通类型。非普通类型因为包含非托管资源,所以它需要继承IDisposable接口,但是,这里包含非托管资源的类型本身,它是一个托管资源。所以,托管资源中的普通类型不需要手动清理,而非普通类型是需要手工清理的(即调用Dispose方法)。
Dispose模式设计的思路是:如果调用者显式调用了Dispose方法,那么类型就应该按部就班地将自己的资源全部释放。如果调用者忘记调用Dispose方法,那么类型就假设自己的所有托管资源(哪怕是那些非普通类型)会全部都交给垃圾回收器回收,所以不进行手工清理。所以在Dispose方法中,虚方法传入参数true,在终结器中,虚方法传入参数false。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
相关文章推荐
- 编写高质量代码改善C#程序的157个建议——建议49:在Dispose模式中应提取一个受保护的虚方法
- C#基础系列——异步编程初探:async和await
- 编写高质量代码改善C#程序的157个建议——建议48:Dispose方法应允许被多次调用
- 编写高质量代码改善C#程序的157个建议——建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理
- AutoCAD.Net/C#.Net QQ群:193522571 将坐标系置为WCS
- 编写高质量代码改善C#程序的157个建议——建议46:显式释放资源需继承接口IDisposable
- C#枚举器接口IEnumerator的实现
- C#调Exe
- 利用Visual Studio寻找C#程序必要的运行库文件
- (转)C#生成中文汉字验证码源码(webform)
- C#名单:一个简单的实现
- C#制作、打包、签名、发布Activex全过程
- C#综合揭秘——细说多线程(下)
- C#综合揭秘——细说多线程(上)
- C#程序关闭时怎么关闭子线程
- C#生成随机验证码
- C#生成验证码
- 无刷新上传图片以及使用C#语言
- C#对Ajax页面内容采集
- C#与yaml解析