Types that own native resources should be disposable
TypeName |
TypesThatOwnNativeResourcesShouldBeDisposable |
CheckId |
CA1049 |
Category |
Microsoft.Design |
Breaking Change |
NonBreaking |
Cause
A type references a System.IntPtr field, a System.UIntPtr field, or a System.Runtime.InteropServices.HandleRef field, but does not implement System.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 allow callers to release those resources on demand and shorten the lifetimes of the objects holding 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 using the System.Object.Finalize method and the System.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 cleaning up the unmanaged resources, Dispose should call the System.GC.SuppressFinalize(System.Object) method to let the garbage collector know that Finalize no longer needs 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 Exclude Warnings
It is safe to exclude a warning from this rule if the type does not reference an unmanaged resource. Otherwise, do not exclude a warning from this rule as 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);
}
}
}
Related Rules
Call GC.KeepAlive when using native resources
Dispose methods should call SuppressFinalize
Disposable types should declare finalizer
Types that own disposable fields should be disposable
See Also
Reference
Implementing Finalize and Dispose to Clean Up Unmanaged Resources