• Implementing a Dispose method


    Implementing a Dispose method

    0、Dispose() and Dispose(Boolean)

      The IDisposable interface requires the implementation of a single parameterless method, DisposeHowever, the dispose pattern requires two Dispose methods to be implemented:

    • A public non-virtual (NonInheritable in Visual Basic) IDisposable.Dispose implementation that has no parameters.

    • A protected virtual (Overridable in Visual Basic) Dispose method whose signature is:

        

    1、Dispose() has a standard implementation, The Dispose method performs all object cleanup, so the garbage collector no longer needs to call the objects' Object.Finalizeoverride.

      实现System.IDsiposable.Dispose()方法。不能将此方法设置为virtual,子类不能override此方法。此方法的实现必须为如下代码。

         // Implement IDisposable.
            // Do not make this method virtual.
            // A derived class should not be able to override this method.
            public void Dispose()
            {
                Dispose(true);
                // This object will be cleaned up by the Dispose method.
                // Therefore, you should call GC.SupressFinalize to
                // take this object off the finalization queue
                // and prevent finalization code for this object
                // from executing a second time.
                GC.SuppressFinalize(this);
            }

    2、实现析构函数(Finalize)。析构函数必须实现为以下代码。

         // Use C# destructor syntax for finalization code.
            // This destructor will run only if the Dispose method
            // does not get called.
            // It gives your base class the opportunity to finalize.
            // Do not provide destructors in types derived from this class.
            ~MyResource()
            {
                // Do not re-create Dispose clean-up code here.
                // Calling Dispose(false) is optimal in terms of
                // readability and maintainability.
                Dispose(false);
            }

    3、实现virtual Dispose(bool disposing)方法,必须为protected。如果dispoing为true,说明从Dipose()方法调用而来;如果为false,说明从析构函数(Finalize)调用而来。在析构函数中,不能再使用引用类型(Ref)成员类型,所以只处理unmanaged resource的释放即可;而在Dipose()调用过程中,managed res & unmanaged res都要释放。

      最后,添加一个成员变量disposed来标记是否已经释放过。

         // Dispose(bool disposing) executes in two distinct scenarios.
            // If disposing equals true, the method has been called directly
            // or indirectly by a user's code. Managed and unmanaged resources
            // can be disposed.
            // If disposing equals false, the method has been called by the
            // runtime from inside the finalizer and you should not reference
            // other objects. Only unmanaged resources can be disposed.
            protected virtual void Dispose(bool disposing)
            {
                // Check to see if Dispose has already been called.
                if(!this.disposed)
                {
                    // If disposing equals true, dispose all managed
                    // and unmanaged resources.
                    if(disposing)
                    {
                        // Dispose managed resources.
                        component.Dispose();
                    }
    
                    // Call the appropriate methods to clean up
                    // unmanaged resources here.
                    // If disposing is false,
                    // only the following code is executed.
                    CloseHandle(handle);
                    handle = IntPtr.Zero;
    
                    // Note disposing has been done.
                    disposed = true;
    
                }
            }

    3.1、Here's the general pattern for implementing the dispose pattern for a derived class that overrides Object.Finalize:

      A class derived from a class that implements the IDisposable interface shouldn't implement IDisposable, because the base class implementation of IDisposable.Dispose is inherited by its derived classes.

     1 using System;
     2 
     3 class DerivedClass : BaseClass
     4 {
     5    // Flag: Has Dispose already been called?
     6    bool disposed = false;
     7    
     8    // Protected implementation of Dispose pattern.
     9    protected override void Dispose(bool disposing)
    10    {
    11       if (disposed)
    12          return; 
    13       
    14       if (disposing) {
    15          // Free any other managed objects here.
    16          //
    17       }
    18       
    19       // Free any unmanaged objects here.
    20       //
    21       disposed = true;
    22       
    23       // Call the base class implementation.
    24       base.Dispose(disposing);
    25    }
    26 
    27    ~DerivedClass()
    28    {
    29       Dispose(false);
    30    }
    31 }

     4、An object must also call the Dispose method of its base class if the base class implements IDisposable

      如果基类有Dispose()方法,子类必须的Dispose()必须调用基类的Dispose()。

     5、什么时候需要Dispose()?

      1)包含Disposable对象的容器类需要实现Dipose,而不需要实现Finalize()。因为清空一个容器,并不表明需要释放unmanged resource。

      2)自身包含unmanged resource的类需实现Dispose、Finalize。

     6、DO throw an ObjectDisposedException from any member that cannot be used after the object has been disposed of.

      当调用一个已经Disposed对象时,抛出 ObjectDisposedException。

    public class DisposableResourceHolder : IDisposable {  
        bool disposed = false;  
        SafeHandle resource; // handle to a resource  
    
        public void DoSomething(){  
               if(disposed) throw new ObjectDisposedException(...);  
            // now call some native methods using the resource   
                ...  
        }  
        protected virtual void Dispose(bool disposing){  
            if(disposed) return;  
            // cleanup  
            ...  
            disposed = true;  
        }  
    }  

    7、一些C#自带类库的Close()语言与Dispose()语义是一样的。

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

    参考:

    1、https://docs.microsoft.com/en-us/dotnet/api/system.idisposable.dispose?view=netframework-4.7.1

    2、https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern

  • 相关阅读:
    Javascript面向对象编程:非构造函数的继承
    JavaScript中this 详解
    构造函数与 new 命令
    JavaScript数组去重的6个方法
    初学Java Web(9)——学生管理系统(简易版)总结
    初学Java Web(8)——过滤器和监听器
    初学Java Web(7)——文件的上传和下载
    初学Java Web(6)——JSP学习总结
    初学Java Web(5)——cookie-session学习
    初学Java Web(4)——Servlet学习总结
  • 原文地址:https://www.cnblogs.com/tekkaman/p/7879077.html
Copyright © 2020-2023  润新知