推荐使用 System.IDisposable 接口替代析构函数
IDisposable接口定义了一种模式,该模式为释放非托管的资源提供了确定的机制,并避免产生析构函数固有的与垃圾回收器相关问题。
IDisposable接口声明了一个 Dispose() 方法, 它不带参数, 返回 void。
class MyClass : IDisposable
{
public void Dispose()
{
// 做点什么
}
}
Dispose() 方法为何时释放非托管资源提供了精确的控制。
假定有一个 ResourceGobbler类, 它需要使用某些外部资源,且实现 IDisposable 接口。 如果要实例化这个类的实例,使用它,然后释放它, 可以使用下面的代码:
var theInstance = new ResourceGobbler();
// 做点什么
theInstance.Dispose();
但是,如果在做点什么的时候出现了异常, 就不会执行 Dispose了,也就不会释放 theInstance 使用的资源。所以使用 try块,来编写下面的代码:
ResourceGobbler theInstance = null;
try
{
theInstance = new ResourceGobbler();
// 做点什么
}
finally
{
theInstance?.Dispose();
}
重点来了!重点来了!重点来了!
使用 try/finally ,即使在处理过程中出现了异常, 也可以确保总是在 theInstance 上调用 Dispose() 方法,总是释放 theInstance使用的任意资源。 但这样的结构总是重复的, 代码就很容易被混淆。 这时候 C# 提供了一种语法,可以确保在实现 IDisposable 接口的对象的引用超出作用域时,在该对象上自动调用 Dispose 方法。
上代码:
using (var theInstance = new ResourceGobbler())
{
// 做点什么
}
上面的代码生成与 try块等价的 IL代码。
需要注意的是 using 这个关键字是不是看着很熟悉呢?
记住 using 关键字在完全不同的环境下,它与名称空间没有关系。在这里叫using语句(非托管资源需要回收时,继承了IDisposable接口的类,使用它就对了)