有几点需要注意:
调用Dispose
方法并不会提高性能。 IDisposable
是为使用受限制或无法由运行时管理的资源的场景而设计的。
没有明确和显然的机制可以告诉编译器如何处理代码中的IDisposable
对象。什么情况下会自动销毁它,什么情况下不会?如果该实例在方法之外被暴露出来,是否应自动销毁?仅仅因为我将一个对象传递给另一个函数或类,并不意味着我希望它在方法作用域之外仍可用。
例如,考虑一个工厂模式,它需要一个Stream
用于反序列化一个类的实例。
public class Foo
{
public static Foo FromStream(System.IO.Stream stream) { ... }
}
而我将其称为:
Stream stream = new FileStream(path);
Foo foo = Foo.FromStream(stream);
现在,当函数退出时,我可能希望或者不希望
Stream
被处理掉。如果
Foo
的工厂从
Stream
中读取了所有必要的数据,并且不再需要它,那么我希望它被处理掉。如果
Foo
对象必须持有流并在其生命周期内使用它,则不希望将其处理掉。
同样,对于从构造函数之外获取的实例(如
Control.CreateGraphics()
),这些实例可以存在于代码之外,因此编译器不会自动处理它们。
给用户控制(并提供像
using
块这样的习惯用语)可以使用户的意图清晰明确,并且更容易发现未正确处理
IDisposable
实例的地方。如果编译器自动释放
某些实例,则调试会更加困难,因为开发人员必须解密自动释放规则如何适用于每个使用
IDisposable
对象的代码块。
最终,按照约定,有两个原因要在类型上实现
IDisposable
。
- 您正在使用非托管资源(意味着您正在进行返回类似句柄的 P/Invoke 调用,该句柄必须通过另一个 P/Invoke 调用释放)
- 该类型具有应在此对象的生命周期结束时处理的
IDisposable
实例
在第一种情况下,所有这些类型都应该实现一个终结器来调用
Dispose
并释放所有
非托管资源(这是为了防止内存和句柄泄漏)。