CA1008:列舉值中應該要有值為零的成員

屬性
規則識別碼 CA1008
標題 列舉值中應該要有值為零的成員
類別 設計
修正程式是中斷或非中斷 非中斷 - 當系統提示您將值新增 None 至非旗標列舉時。 中斷 - 當系統提示您重新命名或移除任何列舉值時。
預設在 .NET 8 中啟用 No

原因

沒有套用 System.FlagsAttribute 的列舉不會定義值為零的成員。 或者,已套用 FlagsAttribute 的列舉會定義成員,其值為零,但其名稱不是 『None』。 或者,列舉會定義多個零值成員。

根據預設,此規則只會查看外部可見的列舉,但這是可設定

檔案描述

未初始化列舉的預設值,就像其他實值型別一樣,是零。 非旗標屬性列舉應該定義具有零值的成員,讓預設值是列舉的有效值。 如果適當,請將成員命名為 『None』 (或其中一個 其他允許的名稱)。 否則,請將零指派給最常使用的成員。 根據預設,如果宣告中未設定第一個列舉成員的值,則其值為零。

如果已 FlagsAttribute 套用 的列舉定義零值成員,其名稱應該是 『None』 (或其中一個 額外的允許名稱),表示列舉中未設定任何值。 針對任何其他用途使用零值成員,與 中的 用法FlagsAttributeAND背道而馳,而OR位運算符與成員一起使用是無用的。 這表示應該只指派一個成員的值零。 如果具有值零的多個成員出現在 flags 屬性化列舉中, Enum.ToString() 則會針對非零的成員傳回不正確的結果。

如何修正違規

若要針對非旗標屬性列舉修正此規則的違規,請定義值為零的成員;這是非中斷性變更。 針對定義零值成員的 flags 屬性列舉,請將這個成員命名為 『None』 並刪除任何其他值為零的成員;這是重大變更。

隱藏警告的時機

除了先前出貨的旗標屬性列舉之外,請勿隱藏此規則的警告。

隱藏警告

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

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

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

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

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

設定程式代碼以分析

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

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

包含特定 API 介面

您可以根據程式代碼基底的存取範圍,設定要執行此規則的部分。 例如,若要指定規則只應該針對非公用 API 介面執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:

dotnet_code_quality.CAXXXX.api_surface = private, internal

其他零值功能變數名稱

在 .NET 7 和更新版本中,除了 之外,您還可以為零值列舉字段 None設定其他允許的名稱。 以 | 字元分隔多個名稱。 下表顯示一些範例。

選項值 摘要
dotnet_code_quality.CA1008.additional_enum_none_names = Never None允許和Never
dotnet_code_quality.CA1008.additional_enum_none_names = Never|Nothing 允許 NoneNeverNothing

範例

下列範例示範兩個滿足規則的列舉,以及違反規則的 列舉 BadTraceOptions

using System;

namespace ca1008
{
    public enum TraceLevel
    {
        Off = 0,
        Error = 1,
        Warning = 2,
        Info = 3,
        Verbose = 4
    }

    [Flags]
    public enum TraceOptions
    {
        None = 0,
        CallStack = 0x01,
        LogicalStack = 0x02,
        DateTime = 0x04,
        Timestamp = 0x08,
    }

    [Flags]
    public enum BadTraceOptions
    {
        CallStack = 0,
        LogicalStack = 0x01,
        DateTime = 0x02,
        Timestamp = 0x04,
    }

    class UseBadTraceOptions
    {
        static void MainTrace()
        {
            // Set the flags.
            BadTraceOptions badOptions =
               BadTraceOptions.LogicalStack | BadTraceOptions.Timestamp;

            // Check whether CallStack is set.
            if ((badOptions & BadTraceOptions.CallStack) ==
                BadTraceOptions.CallStack)
            {
                // This 'if' statement is always true.
            }
        }
    }
}
Imports System

Namespace ca1008

    Public Enum TraceLevel
        Off = 0
        AnError = 1
        Warning = 2
        Info = 3
        Verbose = 4
    End Enum

    <Flags>
    Public Enum TraceOptions
        None = 0
        CallStack = &H1
        LogicalStack = &H2
        DateTime = &H4
        Timestamp = &H8
    End Enum

    <Flags>
    Public Enum BadTraceOptions
        CallStack = 0
        LogicalStack = &H1
        DateTime = &H2
        Timestamp = &H4
    End Enum

    Class UseBadTraceOptions

        Shared Sub Main1008()

            ' Set the flags.
            Dim badOptions As BadTraceOptions =
            BadTraceOptions.LogicalStack Or BadTraceOptions.Timestamp

            ' Check whether CallStack is set.
            If ((badOptions And BadTraceOptions.CallStack) =
             BadTraceOptions.CallStack) Then
                ' This 'If' statement is always true.
            End If

        End Sub

    End Class

End Namespace

另請參閱