我何时应该使用IDisposable,使用它是否错误?Dispose Chaining怎么样?

Fir*_*oso 9 .net garbage-collection idisposable

我真的在寻找一些最佳实践智慧.所以这是问题,如果人们发表评论,我会添加更多.随意回答部分或全部问题.

什么时候我应该使用IDisposable?只有当我有非托管资源时?

配置模式有哪些变化,为什么它们会变化?

我应该注意哪些常见的非托管资源?

实施IDisposable是错误还是误导?

应该将Dispose调用链接在一起,还是应该依赖于使用语句? 例如:

public Dispose(bool disposing)
{
  ...
  this.SomeDependency.Dispose;
}
Run Code Online (Sandbox Code Playgroud)

Rex*_*x M 6

哇.这里有很多问题!

什么时候我应该使用IDisposable?只有当我有非托管资源时?

IDisposable通常用来清理资源,但不一定所有的这是很好的.这是一种通用模式,用于通知正在消耗的对象.一个例子是计时器:

using(var timer = new MyTimer())
{
    //do some stuff
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,调用Dispose不一定是释放任何资源,它只是方便和一致(模式的两个键!)方式告诉计时器"好的,我现在已经完成了"并且计时器可以停止计时,并且可能记录某个地方的时间.

另一个好的经验法则是,如果你需要一个终结器,无论出于什么原因,你通常也应该提供IDisposable对同一例程的访问,这样消费类可以选择提前完成类而不是等待GC.

配置模式有哪些变化,为什么它们会变化?

IDisposable我知道只有一种真正的"特定"类型的实现 - Finalize/Dispose模式:

public class MyClass : IDisposable
{
   void IDisposable.Dispose() 
   {
     Dispose(true);
     GC.SuppressFinalize(this); 
   }

   protected virtual void Dispose(bool disposing) 
   {
      if (disposing) 
      {
         // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
      // Set large fields to null.
   }

   ~MyClass()
   {
      Dispose(false);
   }
}
Run Code Online (Sandbox Code Playgroud)

我应该注意哪些常见的非托管资源?

IDisposable应该假设任何实现的东西,特别是在.NET库中,都有非托管资源的句柄,应该被处理掉.通常,您只能通过这些访问非托管资源.如果没有,你会知道 - 通常建立一个司机或其他东西.

实施IDisposable是错误还是误导?

过度使用它可能毫无意义,但不是直接有害的.

应该将Dispose呼叫链接在一起

类应该只处理它在内部创建的任何IDisposable.如果它具有注入或超出类范围的一次性依赖,则不应丢弃它们.