CA1049: 네이티브 리소스가 있는 형식은 삭제 가능해야 합니다.

항목
RuleId CA1049
범주 Microsoft.Design
주요 변경 내용 주요 변경 아님

원인

형식이 System.IntPtr 필드, System.UIntPtr 필드 또는 System.Runtime.InteropServices.HandleRef 필드를 참조하지만 System.IDisposable을 구현하지 않습니다.

규칙 설명

이 규칙에서 IntPtr, UIntPtr, 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: 삭제 가능한 필드가 있는 형식은 삭제 가능해야 합니다.

참고 항목