CA1001:具有可處置欄位的類型應該為可處置

屬性
規則識別碼 CA1001
職稱 具有可處置欄位的類別必須為可處置
類別 設計
修正是造成中斷還是不中斷 不會中斷 - 若類型在元件外部不可見。

中斷 - 如果類型顯示在元件外部。
在 .NET 10 中預設啟用
適用語言 C# 與 Visual Basic

原因

類別會宣告並實作類型為 System.IDisposable 的實例欄位,而且 類別不會實 IDisposable作 。

根據預設,此規則會分析整個程式碼,但它是可配置的

規則描述

宣告 IDisposable 欄位的類別間接擁有非受控資源。 類別應該實現IDisposable介面,以便在資源不再使用時處理其擁有的未管理資源。 如果類別未直接擁有任何非受控資源,則不應該實作終結器。

此規則會尊重將 System.IAsyncDisposable 作為可處置型別的類型。

如何修正違規

若要修正此規則的違規,請實作 IDisposable 介面。 在 IDisposable.Dispose 方法中,呼叫欄位類型的 Dispose 方法。

隱藏警告的時機

一般而言,請勿隱藏此規則的警告。 當包含類型未保留欄位的處置擁有權時,可以隱藏警告。

隱藏警告

如果您只想要隱藏單一違規,請將預處理器指示詞新增至原始程式檔以停用,然後重新啟用規則。

#pragma warning disable CA1001
// The code that's violating the rule is on this line.
#pragma warning restore CA1001

若要停用檔案、資料夾或專案的規則,請在組態檔中將其嚴重性設為 none

[*.{cs,vb}]
dotnet_diagnostic.CA1001.severity = none

如需詳細資訊,請參閱 如何隱藏程式代碼分析警告

設定程式代碼以分析

使用下列選項來設定程式代碼基底要執行此規則的部分。

這些選項可以只針對此規則、它套用的所有規則,或針對套用至此類別的所有規則(設計)設定。 如需詳細資訊,請參閱 程式代碼品質規則組態選項

排除特定符號

您可以藉由設定 [excluded_symbol_names] 選項,從分析中排除特定符號,例如類型和方法。 例如,若要指定規則不應該在名為 MyType的任何程式代碼上執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

注意

以適用規則的標識碼取代 XXXXCAXXXX 部分。

選項值中允許的符號名稱格式(以 |分隔):

  • 只含符號名稱(包括名稱的所有符號,不論其所屬類型或命名空間)。
  • 符號的 文件識別碼格式中的完整名稱。 每個符號名稱都需要符號種類前置詞,例如 M: 方法、 T: 類型和 N: 命名空間。
  • .ctor 用於建構函式和 .cctor 靜態建構函式。

範例:

選項值 摘要
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType 符合所有名為 MyType的符號。
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 比對名為 MyType1MyType2的所有符號。
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) 比對特定方法 MyMethod 與指定的完整簽章。
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) 比對特定方法 MyMethod1MyMethod2,及其各自的完整簽章。

排除特定類型及其衍生類型

您可以藉由設定 [excluded_type_names_with_derived_types] 選項,從分析中排除特定類型及其衍生類型。 例如,若要指定規則不應該在具名 MyType 類型及其衍生型別內的任何方法上執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

注意

以適用規則的標識碼取代 XXXXCAXXXX 部分。

選項值中允許的符號名稱格式(以 |分隔):

  • 僅輸入類型名稱(包含該名稱的所有類型,不論包含類型或命名空間為何)。
  • 符號的 文件識別碼格式中的完整限定名稱,具有可選的 T: 前置字首。

範例:

選項值 摘要
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType 比對所有具名 MyType 的類型及其所有衍生型別。
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 比對所有名為 MyType1MyType2 的型別,以及其所有衍生型別。
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType 比對指定完整名稱的特定類型 MyType 及其所有衍生類型。
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 比對特定類型 MyType1MyType2 及其所有衍生類型的完整名稱。

範例

下列範例顯示違反規則的類別,以及藉由實 IDisposable作 滿足規則的類別。 類別不會實作完成項,因為 類別不會直接擁有任何 Unmanaged 資源。

Imports System
Imports System.IO

Namespace ca1001

    ' This class violates the rule.
    Public Class NoDisposeMethod

        Dim newFile As FileStream

        Sub New()
            newFile = New FileStream("c:\temp.txt", FileMode.Open)
        End Sub

    End Class

    ' This class satisfies the rule.
    Public Class HasDisposeMethod
        Implements IDisposable

        Dim newFile As FileStream

        Sub New()
            newFile = New FileStream("c:\temp.txt", FileMode.Open)
        End Sub

        Protected Overridable Overloads Sub Dispose(disposing As Boolean)

            If disposing Then
                ' dispose managed resources
                newFile.Close()
            End If

            ' free native resources

        End Sub 'Dispose


        Public Overloads Sub Dispose() Implements IDisposable.Dispose

            Dispose(True)
            GC.SuppressFinalize(Me)

        End Sub 'Dispose

    End Class

End Namespace
// This class violates the rule.
public class NoDisposeMethod
{
    FileStream _newFile;

    public NoDisposeMethod()
    {
        _newFile = new FileStream(@"c:\temp.txt", FileMode.Open);
    }
}

// This class satisfies the rule.
public class HasDisposeMethod : IDisposable
{
    FileStream _newFile;

    public HasDisposeMethod()
    {
        _newFile = new FileStream(@"c:\temp.txt", FileMode.Open);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Dispose managed resources.
            _newFile.Close();
        }
        // Free native resources.
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

另請參閱