如果没有实现终结器,是否需要处理(bool)方法?

时间:2016-08-03 10:12:33

标签: c# .net memory-leaks garbage-collection dispose

虽然在互联网和SOF上广泛讨论了Dispose Pattern,但我找不到任何可以回答我问题的资源。

因此,在将此标记为副本之前,请善意阅读。如果你能指出我之前错过的一个问题,我会很高兴地删除这个问题。

我见过很多类(盲目地?)实现了dispose模式而没有实现终结器。

MSDN article on Dispose Pattern说:

  

布尔参数disposing指示是从IDisposable.Dispose实现还是从终结器调用方法。 Dispose(bool)实现应该在访问其他引用对象(例如,前面示例中的资源字段)之前检查参数。只有在从IDisposable.Dispose实现调用方法时才会访问此类对象(当disposing参数等于true时)。 如果从终结器调用该方法(disposing为false),则不应访问其他对象。原因是对象以不可预测的顺序最终确定,因此它们或它们的任何依赖项可能已经完成。

根据我的理解,GC调用终结器方法(如果实现),而后者又调用Dispose(bool)方法,参数为false。

我的第一个问题是,如果一个类没有实现终结器,那么Dispose(bool)是否会被参数调用为false? (例如我在CLR中发现的某些内容我没有遇到过)

我理解Dispose(bool)可以用来确保对象只被处置一次。

因此,我的第二个问题是,如果某个类不需要实现终结器,那么它是否可以简单地实现如下的Dispose方法?

private bool objectDisposed;
public void Dispose()
{
    if (!objectDisposed)
    {
        // Release/dispose managed resources
        // ...
        // ...

        objectDisposed = true;
    }
}

1 个答案:

答案 0 :(得分:2)

  

我的第一个问题是,如果一个类没有实现终结器   Dispose(bool)是否被调用参数为false? (例如。   通过我没有遇到过的CLR中的某些内容)

NO

  

因此,我的第二个问题是一个班级是否需要实施   一个终结器,然后它可以简单地实现像Dispose方法   下面?

我不会,但你可以。如果你这样做,你将重新发明IDisposable模式,如果这个类将被扩展。正如HansPassant在评论中指出的那样,如果有派生类,IDisposable模式会非常方便。我宁愿在第一时间遵循这个模式。

基础课程

using System;

class BaseClass : IDisposable
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
   { 
      Dispose(true);
      GC.SuppressFinalize(this);           
   }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;
   }

   // Only if there are unmanaged resources.
   ~BaseClass()
   {
      Dispose(false);
   }
}

派生类

using System;

class DerivedClass : BaseClass
{
   // Flag: Has Dispose already been called?
   bool disposed = false;

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) {
         // Free any other managed objects here.
         //
      }

      // Free any unmanaged objects here.
      //
      disposed = true;

      // Call the base class implementation.
      base.Dispose(disposing);
   }

   // Only if there are unmanaged resources.
   ~DerivedClass()
   {
      Dispose(false);
   }
}