Note that there are some explanatory texts on larger screens.

plurals
  1. POMSDN Dispose() example erroneous? (when to set managed references to null)
    primarykey
    data
    text
    <p><a href="http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx#Y630" rel="nofollow noreferrer">MSDN's example pattern</a> for implementing a Dispose() method depicts setting the reference to a disposed managed resource to null (<code>_resource = null</code>), but does so outside the <code>if (disposing)</code> block:</p> <pre><code>protected virtual void Dispose(bool disposing) { // If you need thread safety, use a lock around these // operations, as well as in your methods that use the resource. if (!_disposed) { if (disposing) { if (_resource != null) _resource.Dispose(); Console.WriteLine("Object disposed."); } // Indicate that the instance has been disposed. _resource = null; _disposed = true; } } </code></pre> <p>Shouldn't <code>_resource = null</code> be placed inside this code block? If a call to <code>Dispose(false)</code> is made then <code>_resource</code> will be null and unable to be subsequently disposed! ??</p> <p>Of course, <code>Dispose(false)</code> is only called (in practice) by the runtime during finalization. But if <code>_resource</code> wasn't previously disposed, what is the need to set it to null at this point when the object (including the <code>_resource</code> member field) is about to be garbage collected?</p> <hr> <p>[end of original question]</p> <h1>Follow up:</h1> <p>After much reading, it appears setting the reference to null is not necessary, but may be a good idea for "heavy" member objects if you have reason to believe the containing class (the one being disposed) might not be garbage collected soon.</p> <p>Know that object disposal is no assurance that the object has been "released" by consuming code. The disposed object might be kept around (in a collection or otherwise) for various purposes, or just in error. I can imagine an application that uses objects from a collection then disposes of them, but keeps them in the collection for a later process to perform removal and log final state (or something like that... who knows...)</p> <p><strong>Conclusions:</strong></p> <ol> <li>Setting references to "heavy" member objects to null releases them for garbage collection even if the disposed object is not released.</li> <li>It is overkill to clear references for all objects.</li> <li>Hence, placement of the <code>_resource = null</code> statement (the original question) is not important for two reasons: (A) Using it at all is only something to think about after reading the above; (B) In the MSDN example, it executes for both <code>Dispose(true)</code> and <code>Dispose(false)</code>, but the latter only occurs when the object is finalized and just about to be garbage collected anyway!</li> </ol> <p>Thus, my preference will be to place <code>_resource = null</code> inside the most inner <code>if</code> block:</p> <pre><code>if (disposing) { if (_resource != null) { _resource.Dispose(); _resource = null; } } </code></pre> <p>This keeps all the <code>_resource</code> code together. Further thoughts, anyone?</p> <p>More reading:</p> <ul> <li><a href="https://stackoverflow.com/questions/456551/in-the-disposebool-method-implementation-shouldnt-one-set-members-to-null">In the Dispose(bool) method implementation, Shouldn&#39;t one set members to null?</a></li> <li><a href="https://stackoverflow.com/questions/2926869/c-do-you-need-to-dispose-of-objects-and-set-them-to-null">Do you need to dispose of objects and set them to null?</a></li> <li><a href="http://www.codeproject.com/KB/dotnet/idisposable.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/dotnet/idisposable.aspx</a> (Very good, and long!)</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    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