“File 和 Font 是访问非托管资源(在本例中为文件句柄和设备上下文)的托管类型的示例。还有许多其他类型的非托管资源和封装它们的类库类型。所有此类类型都必须实现 IDisposable 接口。如一条规则,当你使用 IDisposable 对象时,你应该在 using 语句中声明和实例化它。” - MSDN
是否存在应使用 USING 语句的此类情况的列表(访问非托管资源(如 FILE 和 FONT,...)的托管类型?
“File 和 Font 是访问非托管资源(在本例中为文件句柄和设备上下文)的托管类型的示例。还有许多其他类型的非托管资源和封装它们的类库类型。所有此类类型都必须实现 IDisposable 接口。如一条规则,当你使用 IDisposable 对象时,你应该在 using 语句中声明和实例化它。” - MSDN
是否存在应使用 USING 语句的此类情况的列表(访问非托管资源(如 FILE 和 FONT,...)的托管类型?
任何实现的类型IDisposable
,都应该使用using
.
更新(回应评论):using
应该围绕一个IDisposable
类型的实例,假设在更大的范围内不需要它。
正确的做法是总是using
在类型实现接口时使用语句IDisposable
,但要知道规则的异常。
已知异常:
Application
类管理)SystemPens.*
, SystemBrushes.*
(这些静态实例在内部缓存)Icons.*
(这些静态实例在内部缓存)Registry.*
(这些静态实例在内部缓存)AutoResetEvent
, ManualResetEvent
(实际上应该被丢弃,但如果你这样做,请非常小心,因为它可能会导致赛车状况)已知异常列表肯定不完整。
每当您有一个需要确定性清理的资源时,即您希望它有机会在您完成后立即被“销毁”。
更详细地说,IDisposible 接口主要尝试解决.net 语言中缺少“删除”关键字的问题。因为 CLR 是垃圾回收器,所以您永远不知道对象的终结器(析构器)何时运行。在开始释放托管资源之前,GC 可以随意等待。
然而,许多托管资源包装了底层的有限资源——内存并不是唯一必须分配和释放的东西。如前所述,文件句柄是其中之一。数据库处理另一个 - 有无数的例子。为了避免不一致的清理习惯用法,IDisposible 模式用于说“请释放你的有限资源,我已经完成了它们”。因为它内置在框架中,它通过“使用”获得特殊的语言支持,以帮助确保您永远不会忘记调用 Dispose 方法,从而“泄漏”非托管资源。
这并不意味着所有IDisposible 实现者都应该包含在 using 中 - 如果您保留引用并且将来需要它们,您当然不应该包装它们,因为您会导致底层资源的过早释放。仅当您完成对象时才调用 Dispose ,因此仅当您知道在 using 范围结束后已完成该对象时才使用“using”。
因此,正如我们所料,具有确定性破坏的语言,例如 C++/CLI,不需要“使用”。非堆 C++/CLI 对象在超出范围时会自动调用其 Dispose 方法,从而模仿模式试图捕获的析构函数行为。
不,MSDN 文章刚刚告诉您,在使用IDisposable
对象时应该考虑使用它。有许多框架类实现IDisposable
了 ,您肯定也会定义许多自己的。
简单的规则是“任何时候你有一个资源应该在使用后立即释放,而不是在未来某个未知的时刻,当垃圾收集器开始释放它时”。
所有有限的资源,基本上是非托管或托管的。文件、网络套接字、数据库连接、注册表句柄,任何不应该无限期地漂浮的东西。