共用方式為


CA1049:擁有原生資源的型別應為可處置

型別名稱

TypesThatOwnNativeResourcesShouldBeDisposable

CheckId

CA1049

分類

Microsoft.Design

中斷變更

中斷

原因

型別會參考 System.IntPtr 欄位、System.UIntPtr 欄位或 System.Runtime.InteropServices.HandleRef 欄位,但不會實作 System.IDisposable

規則描述

此規則假設 IntPtrUIntPtrHandleRef 欄位會儲存 Unmanaged 資源的指標。配置 Unmanaged 資源的型別應實作 IDisposable,讓呼叫端視需求釋放這些資源,並且縮短儲存資源之物件的存留期 (Lifetime)。

建議用以清除 Unmanaged 資源的設計模式就是同時提供隱含和明確方式,以便分別使用 Object.Finalize 方法和 IDisposable.Dispose 方法釋放這些資源。記憶體回收行程會在物件判斷為不可再執行後的某個不定時間,呼叫物件的 Finalize 方法。在呼叫 Finalize 之後,須有其他記憶體回收行程才能釋放物件。Dispose 方法允許呼叫端依照需求明確釋放資源,並且比資源交給記憶體回收行程還早釋放。在清除 Unmanaged 資源之後,Dispose 應該呼叫 GC.SuppressFinalize 方法,讓記憶體回收行程知道不再需要呼叫 Finalize。這可以消除其他記憶體回收行程的需求,並且縮短物件的存留期。

如何修正違規

若要修正此規則的違規情形,請實作 IDisposable

隱藏警告的時機

如果型別未參考 Unmanaged 資源,則您可以放心地隱藏這項規則的警告。否則,請勿隱藏這項規則的警告,因為實作 IDisposable 失敗會導致 Unmanaged 資源無法使用或無法加以充分利用。

範例

下列範例顯示的型別會實作 IDisposable 以清除 Unmanaged 資源。

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

其他資源

清除 Unmanaged 資源