CA1049: ネイティブ リソースを所有する型は、破棄可能でなければなりません
TypeName |
TypesThatOwnNativeResourcesShouldBeDisposable |
CheckId |
CA1049 |
分類 |
Microsoft.Design |
互換性に影響する変更点 |
なし |
原因
ある型が IntPtr フィールド、UIntPtr フィールド、または HandleRef フィールドを参照していますが、IDisposable を参照していません。
規則の説明
この規則では、IntPtr、UIntPtr、および HandleRef の各フィールドに、アンマネージ リソースへのポインターが格納されていると仮定しています。アンマネージ リソースを割り当てる型では、IDisposable を実装することで、呼び出し元が必要に応じてリソースを解放し、リソースを保持するオブジェクトの有効期間を短縮できるようにする必要があります。
アンマネージ リソースをクリーンアップするデザイン方法として、Object.Finalize メソッド (暗黙的) と IDisposable.Dispose メソッド (明示的) を使用して、リソースを解放する手法を実現することが推奨されます。ガベージ コレクターは、オブジェクトにアクセスできないと判断した後、ある時点でオブジェクトの Finalize メソッドを呼び出します。Finalize が呼び出された後に、追加のガベージ コレクションでオブジェクトを解放する必要があります。Dispose メソッドを使用すると、ガベージ コレクターの処理に任せてリソースを解放する場合よりも早く、呼び出し元の必要に応じて明示的にリソースを解放できます。アンマネージ リソースをクリーンアップした後に、Dispose で GC.SuppressFinalize メソッドを呼び出し、Finalize を呼び出す必要はなくなったことをガベージ コレクターに通知します。これによって、追加のガベージ コレクションが必要なくなり、オブジェクトの有効期間が短くなります。
違反の修正方法
この規則違反を修正するには、IDisposable を実装します。
警告を抑制する状況
型でアンマネージ リソースを参照していない場合は、この規則による警告を抑制しても安全です。それ以外の場合、この規則による警告を抑制しないでください。IDisposable の実装に失敗すると、アンマネージ リソースが使用できなくなったり、十分に活用できなくなったりします。
使用例
アンマネージ リソースをクリーンアップする IDisposable を実装する型を次の例に示します。
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: ネイティブ リソースを使用しているときには GC.KeepAlive を呼び出します
CA1816: GC.SuppressFinalize を正しく呼び出します
CA2216: 破棄できる型ではファイナライザーを宣言します
CA1001: 破棄可能なフィールドを所有する型は、破棄可能でなければなりません
参照
その他の技術情報
Implementing Finalize and Dispose to Clean Up Unmanaged Resources