| 屬性 | 值 |
|---|---|
| 規則識別碼 | CA1008 |
| 職稱 | 列舉應該要包含零值 |
| 類別 | 設計 |
| 修正是造成中斷還是不中斷 | 不間斷 - 當系統提示您將 None 值新增至非旗標列舉時。 中斷 - 當系統提示您重新命名或移除任何列舉值時。 |
| 在 .NET 10 中預設啟用 | 否 |
| 適用語言 | C# 與 Visual Basic |
原因
沒有套用 System.FlagsAttribute 的列舉不會定義值為零的成員。 或者,已套用 FlagsAttribute 的列舉會定義成員,其值為零,但其名稱不是 『None』。 或者,列舉會定義多個零值成員。
根據預設,此規則只會查看外部可見的列舉,但這是可設定的。
規則描述
未初始化列舉的預設值,就像其他實值型別一樣,是零。 非旗標屬性列舉應該定義具有零值的成員,讓預設值是列舉的有效值。 如果適當,請將成員命名為 『None』 (或其中一個 其他允許的名稱)。 否則,請將零指派給最常使用的成員。 根據預設,如果宣告中未設定第一個列舉成員的值,則其值為零。
如果已 FlagsAttribute 套用 的列舉定義零值成員,其名稱應該是 『None』 (或其中一個 額外的允許名稱),表示列舉中未設定任何值。 使用零值成員於任何其他目的,背離了FlagsAttribute的用法,因為與成員一起使用AND和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_surface] 選項,根據程式代碼基底的存取範圍,設定執行此規則的哪些部分。 例如,若要指定規則只應該針對非公用 API 介面執行,請將下列機碼/值組新增至 專案中的 .editorconfig 檔案:
dotnet_code_quality.CAXXXX.api_surface = private, internal
注意
以適用規則的標識碼取代 XXXX 的 CAXXXX 部分。
其他零值欄位名稱
在 .NET 7 和更新版本中,除了 之外,您還可以為零值列舉字段 None設定其他允許的名稱。 以 | 字元分隔多個名稱。 下表顯示一些範例。
| 選項值 | 摘要 |
|---|---|
dotnet_code_quality.CA1008.additional_enum_none_names = Never |
同時允許None和Never |
dotnet_code_quality.CA1008.additional_enum_none_names = Never|Nothing |
允許 None、 Never和 Nothing |
範例
下列範例示範兩個滿足規則的列舉,以及違反規則的 列舉 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
相關規則
- CA2217:不要以 FlagsAttribute 標記列舉
- CA1700:不要在列舉值名稱中包含 'Reserved'
- CA1712: 不要為枚舉值加上類型名稱的前綴
- CA1028:列舉儲存區應該是 Int32
- CA1027: 必須使用 FlagsAttribute 標記列舉