CA1049:擁有原生資源的型別應為可處置
型別名稱 |
TypesThatOwnNativeResourcesShouldBeDisposable |
CheckId |
CA1049 |
分類 |
Microsoft.Design |
中斷變更 |
中斷 |
原因
型別會參考 System.IntPtr 欄位、System.UIntPtr 欄位或 System.Runtime.InteropServices.HandleRef 欄位,但不會實作 System.IDisposable。
規則描述
此規則假設 IntPtr、UIntPtr 和 HandleRef 欄位會儲存 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
請參閱
參考
實作 Finalize 和 Dispose 以清除 Unmanaged 資源