CA1049: Types that own native resources should be disposable

TypeName

TypesThatOwnNativeResourcesShouldBeDisposable

CheckId

CA1049

Category

Microsoft.Design

Breaking Change

Non-breaking

Cause

A type references a IntPtr field, a UIntPtr field, or a HandleRef field, but does not implement IDisposable.

Rule Description

This rule assumes that IntPtr, UIntPtr, and HandleRef fields store pointers to unmanaged resources. Types that allocate unmanaged resources should implement IDisposable to let callers to release those resources on demand and shorten the lifetimes of the objects that hold the resources.

The recommended design pattern to clean up unmanaged resources is to provide both an implicit and an explicit means to free those resources by using the Object.Finalize method and the IDisposable.Dispose method, respectively. The garbage collector calls the Finalize method of an object at some indeterminate time after the object is determined to be no longer reachable. After Finalize is called, an additional garbage collection is required to free the object. The Dispose method allows the caller to explicitly release resources on demand, earlier than the resources would be released if left to the garbage collector. After it cleans up the unmanaged resources, Dispose should call the GC.SuppressFinalize method to let the garbage collector know that Finalize no longer has to be called; this eliminates the need for the additional garbage collection and shortens the lifetime of the object.

How to Fix Violations

To fix a violation of this rule, implement IDisposable.

When to Suppress Warnings

It is safe to suppress a warning from this rule if the type does not reference an unmanaged resource. Otherwise, do not suppress a warning from this rule because failure to implement IDisposable can cause unmanaged resources to become unavailable or underused.

Example

The following example shows a type that implements IDisposable to clean up an unmanaged resource.

Imports System

Namespace DesignLibrary

    Public Class UnmanagedResources
        Implements IDisposable

       Dim unmanagedResource As IntPtr
       Dim disposed As Boolean = False 

       Sub New  
           ' Allocate the unmanaged resource ... 
       End Sub 

       Overloads Sub Dispose() Implements IDisposable.Dispose
           Dispose(True)
           GC.SuppressFinalize(Me)
       End Sub 

       Protected Overloads Overridable Sub Dispose(disposing As Boolean)
           If Not(disposed) Then 

               If(disposing) Then 
                   ' Release managed resources. 
               End If 

               ' Free the unmanaged resource ...

               unmanagedResource = IntPtr.Zero

               disposed = True 

           End If 
       End Sub 

       Protected Overrides Sub Finalize()
           Dispose(False)
       End Sub 

    End Class 

End Namespace
using System;

namespace DesignLibrary
{
    public class UnmanagedResources : IDisposable
    {
        IntPtr unmanagedResource;
        bool disposed = false;

        public UnmanagedResources() 
        {
            // Allocate the unmanaged resource ...
        }

        public void Dispose() 
        {
            Dispose(true);
            GC.SuppressFinalize(this); 
        }

        protected virtual void Dispose(bool disposing)
        {
            if(!disposed)
            {
                if(disposing)
                {
                    // Release managed resources.
                }

                // Free the unmanaged resource ...

                unmanagedResource = IntPtr.Zero;

                disposed = true;
            }
        }

        ~UnmanagedResources()
        {
            Dispose(false);
        }
    }
}

CA2115: Call GC.KeepAlive when using native resources

CA1816: Call GC.SuppressFinalize correctly

CA2216: Disposable types should declare finalizer

CA1001: Types that own disposable fields should be disposable

See Also

Reference

Dispose Pattern

Other Resources

Cleaning Up Unmanaged Resources