【问题标题】:Why IDisposable interface? [duplicate]为什么是 IDisposable 接口? [复制]
【发布时间】:2020-11-09 14:00:01
【问题描述】:

我看过很多文章说 IDisposable 的目的是关闭非托管对象,如数据库连接和第三方报告。但我的问题是,如果我可以在我的方法中处理非托管对象,我为什么要定义 Dispose 方法没有定义 Dispose() 方法?

举个例子,

class Report : IDisposable
{
    public void GenerateReport()
    {
        Report rpt=new Report() //unmanaged object created
        rpt.Dispose(); // Disposing the unmanaged object
    }

    private void Dispose()
    {
        //not sure why this block is needed
    }
}

我的理解正确吗?

【问题讨论】:

  • 嗨,杰。您可能会在stackoverflow.com/questions/538060/… 找到您的问题(以及许多其他问题!)的答案。此外,如果这个问题最终被标记为重复,请不要感到惊讶 - 它之前已经介绍过:-)

标签: c# .net


【解决方案1】:

垃圾收集器 (GC) 可在整个 .Net 框架中使用,运行良好,很容易被遗忘。但是,值得学习与他一起工作并利用他的可能性。为此,IDisposable 接口的正确实现是必要的,如果我们考虑适当释放托管和非托管资源,则其基本形式有时是不够的。

这是扩展版本,在这种情况下非常有用。 在某种程度上回答了你的问题:

public class DisposableExtended: IDisposable
{
   private bool isDisposed = false;

public void Dispose ()
{
   this.Dispose (true);
   GC.SupressFinalize (this);
}
protected void Dispose (bool disposing)
{
     if (! this.isDisposed)
     {
            if (disposing)
            {
             // here we release managed resources (standard classes)
            }
           // here we release unmanaged resources (e.g. streams, etc..)

     {
}

}
  this .isDisposed = true;
}

~ DisposableExtended ()
{
  this.Dispose (false);
}

【讨论】:

    【解决方案2】:

    实现 IDisposable 接口的类可以在 using 块中使用。此解决方案的一大优点是,在离开块后,将自动调用在该区域中创建的对象的 Dispose 方法。这样,我们只能使用实现 IDisposable 接口的类。

    //example :
    using(var dClean= new DisposableClean())
    {
        //after leaving this using dClean will be automatically destroyed 
    }
    

    您创建的对象需要公开一些方法,而不是必须命名为 Dispose()。你也可以称它为 Clean()。 Dispose() 是常规名称。

    【讨论】:

      【解决方案3】:

      是的,您可以定义自己的方式来释放资源,但许多现有代码都使用这种方式。如果您将代码分享给他人,请记住告诉他们以您的方式处理。

      实现IDisposable 的一个“好处”是您可以通过使用诸如using 之类的语言结构间接调用Dispose

      例如:

      using(Stream s = File.OpenRead("HelloWorld.bin"))
                  {
                      //Do stuffs
                  }
      

      【讨论】:

        【解决方案4】:

        您是正确的,您的示例中不需要实现 IDisposable。示例是,如果您在编写的课程的生命周期内保留一个长寿命的对象。所以说你有这个:

        public class Report : IDisposable
        {
          private Stream _reportStream; // This variable lives a long time.
        
          public void WriteToStream(byte[] data)
          {
            _reportStream.Write(data, 0, data.Length);
          }
        
          public void Dispose()
          {
            _reportStream?.Dispose();
          }
        }
        

        这是一个相当简单的示例,但它表明_reportStream 在类的长度内存在,并且需要与类同时进行清理和垃圾收集。没有什么能阻止你创建一个名为 CleanupObject() 的公共方法来做同样的事情,但是人们不能使用 using 块让运行时自动调用 Dispose():

        using (var myReport = new Report())
        {
          // do a bunch of things with myReport;
        } // Here the runtime will call myReport.Dispose() for you.
        
        // myReport isn't accessible from here, as it was declared in the using block
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-04-16
          • 2011-02-25
          • 2013-01-11
          • 1970-01-01
          • 1970-01-01
          • 2012-03-16
          • 1970-01-01
          • 2017-03-29
          相关资源
          最近更新 更多