.Net中Dispose()和Close()的区别

来源:互联网 发布:软件需求统计表 编辑:程序博客网 时间:2024/05/01 20:30
最近准备跟朋友合作起草一个基础的系列视频教程,于是挖掘了一下基本的东西,有时候基本的也是很有意思的,反倒是更深层次的。比如Disponse()和Close()二者的区别和关系,以前就没有在意过为什么是这样设计的。

    有时候有人会问如下的问题:当我们开发C#代码的时候,经常碰到一个问题,有些class提供Close(),有些class提供Dispose(),而且有些class里面还提供了Dispose(bool),那么Dispose和Close到底有什么区别?

 

一、Close()更直观吧?!

    可能Close()是为了那些不熟悉Dispose()的开发者设计的,因为基本上所有的开发者都知道Close()是干什么用的,毕竟它有一个比较直观的名字。但是我想这不是主要原因,主要原因在于设计模式。

 

二、Close()和Dispose()的设计模式

    在.Net Framework里,Close()被设计成public的,并且在Close()里面调用被隐藏的Dispose(); 而后Dispose()再去调用另一个virtual的Dispose(bool)函数。所以如果从这个class继承,你就必须实现Dispose(bool)方法。调用者通过调用Close()就会间接调用到你重载的那个Dispose(bool)方法去释放资源了。

 

三、Close()不应该被定义成virtual

    因为Close()只是用来呼叫那个隐藏的Dispose()继而呼叫Dispose(bool)的,用户不应该改变Close的行为。对于这一点来说,System.IO.Stream是存在设计问题的。原因可能是为了满足向下兼容的需要。所以,我们在MSDN文档里面可以查到:虽然Close()是virtual的,但是不应该被override。   

 

四、IDisposable接口的实现模式

    具有Disponse()方法的类是实现了IDisposable接口的。.Net中很多Class只提供Close(),而不对外提供Disponse(), 但是它的确是实现了IDisponse接口,这是为什么呢?

    究其原因是因为接口的实现模式——显式实现 / 隐式实现,二者的区别:对于隐式实现来说,你只需要调用"new ClassA().Dispose()",但是对于显式实现来说,Dispose()不会是这个ClassA的成员函数。唯一的调用方式是你先要强制类型转换到IDisposable才行,即"new ClassA().Dispose()"编译不过,但是((IDisposable)new ClassA()).Dispose()可以编译过。所以这样就符合了设计的要求:提供Close(),隐藏Dispose(),并且实现了IDisposable接口。