Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
Previous Versions
.NET Framework 3.0
Tools
Development Tools
FxCop
FxCop Warnings
Design Warnings
 Implement IDisposable Correctly
Collapse All/Expand All Collapse All
This page is specific to
Microsoft Visual Studio 2005/.NET Framework 2.0

Other versions are also available for the following:
Visual Studio Team System
Implement IDisposable Correctly

TypeName

ImplementIDisposableCorrectly

CheckId

CA10634

Category

Microsoft.Design

Breaking Change

NonBreaking

IDisposable is not implemented correctly. Some reasons for this problem are listed here:

  • IDisposable is re-implemented in the class.

  • Finalize is re-overridden.

  • Dispose is overridden.

  • Dispose() is not public, sealed, or named Dispose.

  • Dispose(bool) is not protected, virtual, or unsealed.

  • In unsealed types, Dispose() must call Dispose(true).

  • For unsealed types, the Finalize implementation does not call either or both Dispose(bool) or the case class finalizer.

  1. Violation of any of these patterns will trigger this warning.

  2. Every unsealed root IDisposable type must provide its own protected virtual void Dispose(bool) method. Dispose() should call Dipose(true) and Finalize should call Dispose(false). If you are creating an unsealed root IDisposable type, you must define Dispose(bool) and call it.

  3. The following pseudo-code provides a general example of how Dispose(bool) should be implemented in a class that uses managed and native resources:

public class Resource : IDisposable 
{
    private IntPtr nativeResource = Marhsal.AllocHGlobal(100);
    private AnotherResource managedResource = new AnotherResource();

// Dispose() calls Dispose(true)
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    // NOTE: Leave out the finalizer altogether if this class doesn't 
    // own unmanaged resources itself, but leave the other methods
    // exactly as they are. 
    ~Resource() 
    {
        // Finalizer calls Dispose(false)
        Dispose(false);
    }
    // The bulk of the clean-up code is implemented in Dispose(bool)
    protected virtual void Dispose(bool disposing)
    {
        if (disposing) 
        {
            // free managed resources
            if (managedResource != null)
            {
                managedResource.Dispose();
                managedResource = null;
            }
        }
        // free native resources if there are any.
        if (nativeResource != IntPtr.Zero) 
        {
            Marshal.FreeHGlobal(nativeResource);
            nativeResource = IntPtr.Zero;
        }
    }
}

All IDisposable types should implement the Dispose pattern correctly.

Examine your code and determine which of the following resolutions will fix this violation.

  • Remove IDisposable from the list of interfaces implemented by {0} and override the base class Dispose implementation instead.

  • Remove the finalizer from type {0}, override Dispose(bool disposing), and put the finalization logic in the code path where 'disposing' is false.

  • Remove {0}, override Dispose(bool disposing), and put the dispose logic in the code path where 'disposing' is true.

  • Ensure that {0} is declared as public and sealed.

  • Rename {0} to 'Dispose' and ensure that it is declared as public and sealed.

  • Ensure that {0} is declared as protected, virtual, and unsealed.

  • Modify {0} so that it calls Dispose(true), then calls GC.SuppressFinalize on the current object instance ('this' or 'Me' in Visual Basic), and then returns.

  • Modify {0} so that it calls Dispose(false) and then returns.

  • If writing an unsealed root IDisposable class, ensure that the implementation of IDisposable follows the pattern described above.

Do not exclude a warning from this rule.

Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Visual C++ 2005 compiler generated finalizer will trigger this message      Sheng Jiang 蒋晟   |   Edit   |   Show History

The compiler in Visual C++ 2005 generats a finalizer for the following example that will trigger this message

public ref class MyForm : System::Windows::Forms::Form
{
.....
~MyForm()
{
if (components)
{
delete components;
}
this->!MyForm();
}
!MyForm()
{
//free unmanaged resources
}
}

Tags What's this?: Add a tag
Flag as ContentBug
Should we need to set the object to null?      GayanDev   |   Edit   |   Show History
in the very first MS code snippet, it says to clean up managed resources, using the following way:

managedResource.Dispose();
managedResource = null;

assuming managedResource has a Dispose method which again set some managed resources to null, it would be

class managedResource
{
protected virtual void Dispose(bool disposing)
{
anotherUnmanagedRes.Dispose();
anotherUnmanagedRes = null;
}

}

meaning: it will only set the managed resources' references to null in a chain.

If Im correct, that means, we just set the objects ready for GC rather than destroying it right there. Alternatively we can set the managed resources to null only (without implementing Dispose()) if we have managed resources if this is the case, can't we?

Any feedbacks would be really appreciated on this.
Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement | Site Feedback
Page view tracker