Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Note that any IDisposable implementation should follow the below pattern (IMHO). I developed this pattern based on info from several excellent .NET "gods" the <a href="http://rads.stackoverflow.com/amzn/click/0321545613" rel="noreferrer">.NET Framework Design Guidelines</a> (note that MSDN does not follow this for some reason!). The .NET Framework Design Guidelines were written by Krzysztof Cwalina (CLR Architect at the time) and Brad Abrams (I believe the CLR Program Manager at the time) and Bill Wagner ([Effective C#] and [More Effective C#] (just take a look for these on Amazon.com:</p> <p>Note that you should NEVER implement a Finalizer unless your class directly contains (not inherits) UNmanaged resources. Once you implement a Finalizer in a class, even if it is never called, it is guaranteed to live for an extra collection. It is automatically placed on the Finalization Queue (which runs on a single thread). Also, one very important note...all code executed within a Finalizer (should you need to implement one) MUST be thread-safe AND exception-safe! BAD things will happen otherwise...(i.e. undetermined behavior and in the case of an exception, a fatal unrecoverable application crash).</p> <p>The pattern I've put together (and written a code snippet for) follows:</p> <pre><code>#region IDisposable implementation //TODO remember to make this class inherit from IDisposable -&gt; $className$ : IDisposable // Default initialization for a bool is 'false' private bool IsDisposed { get; set; } /// &lt;summary&gt; /// Implementation of Dispose according to .NET Framework Design Guidelines. /// &lt;/summary&gt; /// &lt;remarks&gt;Do not make this method virtual. /// A derived class should not be able to override this method. /// &lt;/remarks&gt; 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. // Always use SuppressFinalize() in case a subclass // of this type implements a finalizer. GC.SuppressFinalize( this ); } /// &lt;summary&gt; /// Overloaded Implementation of Dispose. /// &lt;/summary&gt; /// &lt;param name="isDisposing"&gt;&lt;/param&gt; /// &lt;remarks&gt; /// &lt;para&gt;&lt;list type="bulleted"&gt;Dispose(bool isDisposing) executes in two distinct scenarios. /// &lt;item&gt;If &lt;paramref name="isDisposing"/&gt; equals true, the method has been called directly /// or indirectly by a user's code. Managed and unmanaged resources /// can be disposed.&lt;/item&gt; /// &lt;item&gt;If &lt;paramref name="isDisposing"/&gt; 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.&lt;/item&gt;&lt;/list&gt;&lt;/para&gt; /// &lt;/remarks&gt; protected virtual void Dispose( bool isDisposing ) { // TODO If you need thread safety, use a lock around these // operations, as well as in your methods that use the resource. try { if( !this.IsDisposed ) { if( isDisposing ) { // TODO Release all managed resources here $end$ } // TODO Release all unmanaged resources here // TODO explicitly set root references to null to expressly tell the GarbageCollector // that the resources have been disposed of and its ok to release the memory allocated for them. } } finally { // explicitly call the base class Dispose implementation base.Dispose( isDisposing ); this.IsDisposed = true; } } //TODO Uncomment this code if this class will contain members which are UNmanaged // ///// &lt;summary&gt;Finalizer for $className$&lt;/summary&gt; ///// &lt;remarks&gt;This finalizer will run only if the Dispose method does not get called. ///// It gives your base class the opportunity to finalize. ///// DO NOT provide finalizers in types derived from this class. ///// All code executed within a Finalizer MUST be thread-safe!&lt;/remarks&gt; // ~$className$() // { // Dispose( false ); // } #endregion IDisposable implementation </code></pre> <p>Here is the code for implementing IDisposable in a derived class. Note that you do not need to explicitly list inheritance from IDisposable in the definition of the derived class.</p> <pre><code>public DerivedClass : BaseClass, IDisposable (remove the IDisposable because it is inherited from BaseClass) protected override void Dispose( bool isDisposing ) { try { if ( !this.IsDisposed ) { if ( isDisposing ) { // Release all managed resources here } } } finally { // explicitly call the base class Dispose implementation base.Dispose( isDisposing ); } } </code></pre> <p>I've posted this implementation on my blog at: <a href="http://dave-black.blogspot.com/2011/03/how-do-you-properly-implement.html" rel="noreferrer">How to Properly Implement the Dispose Pattern</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload