有些对象需要在你完成后采取一些行动。通常这是因为对象使用了某种需要处理的资源。例如,如果您有一个 File 类的文件对象,并且该对象从文件系统中打开一个文件,则需要再次关闭文件系统中的文件。
如果您只是离开了文件对象,而忘记调用 file.Close(),则在垃圾收集器 (GC) 运行并发现没有任何东西仍在使用文件对象之前,它不会被清理。垃圾收集器何时运行应该留给公共语言运行时 (CLR) 来决定。如果在您处理完文件后 GC 有一段时间没有运行,则该文件可能会长时间保持打开状态。如果有很多文件对象,或者有东西想打开一个文件,但因为你留下的文件对象还在附近,这可能会造成很大的问题。
为了解决这个问题,C# 提供了 IDisposable 接口。这有一种称为 Dispose 的方法。需要一些清理的类实现了这个 Dispose 方法。这为您提供了一种清理任何使用资源的对象的标准方法。有很多类需要调用 Dispose。这样做的问题是代码被对 Dispose 的调用所覆盖,并且它们很难遵循,因为您新建对象并调用 Dispose 以清理它的位置不同。因此,您必须仔细查看代码并非常小心地检查是否在正确的位置调用了 Dispose。
为了解决这个问题,C# 引入了 'using' 关键字。您可以在新建对象的位置放置一个“使用”关键字,这样可以确保为您调用 Dispose。它保证无论发生什么都会调用 Dispose ......即使在 using 语句的主体内抛出异常。
因此,当您想确保分配资源的对象将被清理时,您应该使用“使用”。
using 只能用于在堆栈上声明的对象,即在函数中。它不适用于声明为类成员的对象。对于他们,您必须自己调用 Dispose。您可能必须在您的类中实现 Dispose,以便在它拥有的任何需要它的成员对象上调用 Dispose。
需要调用的常用对象有:文件、数据库连接、Pen 和 Brush 等图形对象。
有时当您希望两个操作一起发生时也使用它。例如,如果您想在输入代码块和退出代码块时编写日志语句,您可以编写一个可以像这样使用的日志类:
using( Log log = new Log("Doing stuff") )
{
// Stuff
}
日志类的构造函数可以写出消息,Dispose方法也可以写出。实现终结器 (~Log) 以断言是否未调用 Dispose 方法以确保在“新日志”周围记住“使用”。