Share via


CA1049: ネイティブ リソースを所有する型は、破棄可能でなければなりません

Item [値]
規則 ID CA1049
カテゴリ Microsoft.Design
互換性に影響する変更点 なし

原因

型が、System.IntPtr フィールド、System.UIntPtr フィールド、または System.Runtime.InteropServices.HandleRef フィールドを参照しますが、System.IDisposable を実装していません。

規則の説明

この規則は、IntPtrUIntPtr、および HandleRef フィールドにアンマネージド リソースへのポインターが格納されていることを前提としています。 アンマネージド リソースを割り当てる型では、IDisposable を実装することで、呼び出し元が必要に応じてリソースを解放し、リソースを保持するオブジェクトの有効期間を短縮できるようにする必要があります。

アンマネージド リソースをクリーンアップするために推奨される設計パターンは、これらのリソースを解放するための暗黙的な手段と明示的な手段の両方 (それぞれ、System.Object.Finalize メソッドと System.IDisposable.Dispose メソッドを使用) を提供することです。 ガベージ コレクターは、オブジェクトが到達不能になったと判断した後、不特定の時点でオブジェクトの Finalize メソッドを呼び出します。 Finalize が呼び出された後、オブジェクトを解放するには、追加のガベージ コレクションが必要です。 Dispose メソッドを使用すると、呼び出し元では、ガベージ コレクターに残されている場合のリソースの解放タイミングより早く、リソースを明示的に解放することができます。 アンマネージド リソースがクリーンアップされた後、Dispose では System.GC.SuppressFinalize メソッドを呼び出して、Finalize の呼び出しが不要になったことをガベージ コレクターに知らせる必要があります。これにより、追加のガベージ コレクションが不要になり、オブジェクトの有効期間が短縮されます。

違反の修正方法

この規則の違反を修正するには、IDisposable を実装します。

どのようなときに警告を抑制するか

この型でアンマネージド リソースを参照することがないのであれば、この規則による警告を抑制しても問題ありません。 それ以外の場合は、IDisposable の実装に失敗すると、アンマネージド リソースの使用ができなくなったり不十分になったりする可能性があるため、この規則による警告は抑制しないでください。

次の例は、アンマネージド リソースをクリーンアップするために IDisposable を実装する型を示しています。

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:破棄可能なフィールドを所有する型は、破棄可能でなければなりません

関連項目