关于IDisposable的问题

我的问题是为什么我需要IDisposable? 我有一个类消耗一些需要释放的资源。 我有两个选择

没有IDisposable

class SomeUtilityClass { public Stop() { // free resources } } 

使用IDisposable

  class SomeUtilityClass, IDisposable { public void Dispose() { // free resources } } 

那我为什么需要IDisposable呢? 它没有如何命名该function。

 class Program { public Main(..) { SomeUtilityClass _class = new SomeUtilityClass(); // clean up when we've done _class.Stop(); // OR _class.Dispose(); } } 

因为IDis支持IDisposable,你可以使用cool using语法:

 using (IDisposable someDisposable = new ...) { // your code with someDisposable } 

这实际上是由编译器转换为:

 IDisposable someDisposable = new ... IDisposable someDisposable2 = someDisposable ; try { // your code with someDisposable } finally { if (someDisposable2 != null) { someDisposable2.Dispose(); } } 

因此,如果在using块内部发生任何exception,则无论如何都会处理对象。

当您的类消耗非托管资源时,您应该只使用IDisposable,并且需要立即释放它们(流,数据库等)。

当还有未处理的exception导致您的线程被卸载时,它还为CLR提供了一种“清理”的方法。

调用IDisposable会将对象标记为可立即用于垃圾收集,但如果未正确实现,则可能导致对象被提升为垃圾收集生成,这可能会导致内存压力(如果需要完整说明,请参阅通过c#3的Jeffery Richters CLR )。

一个快速的谷歌转向了这个: http : //kleahy-technical.blogspot.com/2009/01/idisposable-and-garbage-collection.html

我建议你阅读IDisposable模式,何时使用它,何时不使用它及其对GC和状态的影响。

编辑:stackoverflow上也有大量的信息: 使用垃圾收集?

那么在你的情况下,实现IDisposable没有多大意义,因为你可以手动处理你的资源。

IDisposable的一个常见用途是当您公开处理数据连接的接口时,您希望所有派生类在完成后进行处置。

考虑一下:

 public interface IDataCtx { void CallDB(); } public class MyDataCtx : IDataCtx { private SqlConnection dc; public MyDataCtx() { dc = new SqlConnection(); dc.Open(); } public void CallDB(); { dc.Something(); } } 

允许你做这样的事情:

 IDataCtx ctx = new MyDataCtx(); ctx.CallDB(); 

但等等,那个开放的连接怎么样? 哦哦!

如果你创建了IDataCtx : IDisposable (并在你的派生ctx中实现了代码),你可以这样做:

 IDataCtx ctx; using (ctx = new MyDataCtx()) { ctx.CallDB(); } 

保证无论您使用何种IDataCtx,它都将被处理掉(即使在例外的情况下)。

无论如何,这就是我如何使用它。 (加上它只是一个好习惯)。

IDisposableusing关键字交互,以便在自己之后轻松清理,例如:

 using (var file = new FileStream(...)) { file.Write(...); } 

在上面的代码中, FileStream在using块完成后立即关闭,而不是等待垃圾收集。

这是C#语言中使用的约定。

您还可以获得漂亮的using声明。

 using (SomeUtilityClass _class = new SomeUtilityClass()) { } // Dispose is automatically called 

除了能够使用using语句之外,它还为垃圾收集器提供了一个提示,即可以从内存中删除该对象。

如果您的类拥有非托管资源或您的类拥有托管的IDisposable资源,那么您应该实现IDisposable接口。

关于何时实现IDisposable和Finalizer的简单易读的小文章可以在这里找到: http : //nitoprograms.blogspot.com/2009/08/how-to-implement-idisposable-and.html