tags:

views:

180

answers:

4

the following code is from MSDN: Idisposable pattern

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;   
        }
    }

why the following statement:

 _resource = null;  
_disposed = true; 

are not enclosed by if (disposing) statement block?

for me i would probably write like this:

if (disposing) {
       if (_resource != null) {
            _resource.Dispose();
            _resource = null;
            _disposed = true;
           }
         Console.WriteLine("Object disposed.");
   }

anything wrong with my version?

+1  A: 

After the call to Dispose() the resource should always be marked as disposed because otherwise you could run into problems. So even if _resource is null, you need to mark it as disposed.

Running

_resource = null;

doesn't hurt even if the resource was null at the first place.

Aurril
+1  A: 

Yes ;)

Ok, the _resource = null - has IMHO to go in as you said. The sample code is sloppy here, sorry ;) I also prefer it your way.

_disposed = true, though, is INDEPENDENT on the existence if _resource. It should ALSO be set if the _resource pointer has not been initialized to start with, so it should go DIRECTLY above the Console.WriteLine. Imagine a situation where the _resource is a file handler, which is opened during a method call in the classs - there may be scenarios where the class is created, but the file handler not, and in this case dispose has to also function.

if (disposing) {
if (_resource != null) {
_resource.Dispose();
_resource = null;
}
_disposed = true;
Console.WriteLine("Object disposed.");
}

is how I would write it.

TomTom
+1  A: 

The pattern outlined by the MSDN is the only correct way to implement IDisposable because it takes finalization into account. You need to look closely at the IDisposable implementation:

public void Dispose() 
{
    Dispose(true);

    // Use SupressFinalize in case a subclass
    // of this type implements a finalizer.
    GC.SuppressFinalize(this);      
}

This calls your dispose method, indicating it's a real dispose and supresses further finalization.

It's not safe to call out to any other object during finalization, so that's why you want to set:

 _resource = null;  
_disposed = true; 

to prevent any further mishappenings.

Here's a good info on finalization and IDisposable on MSDN.

Johannes Rudolph
+1  A: 

The Dispose(bool) function is usually called both from Dispose() and from the Finalizer (named ~Class in C#). When called by the finalizer, garbage collection is already underway, and the order of garbage collection between different objects is not defined. The garbage collector might very well have destroyed _resource already, so it's only when Dispose(bool) is called from Dispose() that we want to destroy "child resources" (This is true for managed resources, unmanaged resources should always be freed)

Anders Abel