Should IDisposable.Dispose() be made safe to call multiple times?

前端 未结 4 1654
一向
一向 2020-11-30 08:08

Should implementations of IDisposable make Dispose() safe to call multiple times? Or the opposite? What approach to most .NET Framework classes take?

Specifically, i

4条回答
  •  被撕碎了的回忆
    2020-11-30 09:03

    If an object is disposed you shouldn't be disposing of it a second time.This helps you to not prolong the life of the object in the Garbage Collector.

    A pattern I use normally is this.

    // A base class that implements IDisposable.
    // By implementing IDisposable, you are announcing that
    // instances of this type allocate scarce resources.
    public class BaseClass: IDisposable
    {
        /// 
        /// A value indicating whether this instance of the given entity has 
        /// been disposed.
        /// 
        /// 
        ///  if this instance has been disposed; otherwise, 
        /// .
        /// 
        /// 
        /// If the entity is disposed, it must not be disposed a second
        /// time. The isDisposed field is set the first time the entity
        /// is disposed. If the isDisposed field is true, then the Dispose()
        /// method will not dispose again. This help not to prolong the entity's
        /// life in the Garbage Collector.
        /// 
        private bool isDisposed;
    
       /// 
        /// Disposes the object and frees resources for the Garbage Collector.
        /// 
        public void Dispose()
        {
            this.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);
        }
    
        /// 
        /// Disposes the object and frees resources for the Garbage Collector.
        /// 
        /// If true, the object gets disposed.
        protected virtual void Dispose(bool disposing)
        {
            if (this.isDisposed)
            {
                return;
            }
    
            if (disposing)
            {
                // Dispose of any managed resources here.
    
            }
    
            // Call the appropriate methods to clean up
            // unmanaged resources here.
            // Note disposing is done.
            this.isDisposed = true;
    
        }
    
        // 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.
        ~BaseClass()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(false);
        }      
    }
    

提交回复
热议问题