CA1008:枚举应具有零值
属性 | 值 |
---|---|
规则 ID | CA1008 |
标题 | 枚举应具有零值 |
类别 | 设计 |
修复是中断修复还是非中断修复 | 非中断 - 如果系统提示你向无标志枚举添加 None 值。 中断 - 如果系统提示你重命名或删除任何枚举值。 |
在 .NET 9 中默认启用 | 否 |
原因
没有应用 System.FlagsAttribute 的枚举不定义值为零的成员。 或者,已应用 FlagsAttribute 的枚举定义值为零但其名称不为“None”的成员。 或者,枚举定义多个零值成员。
默认情况下,此规则仅查看外部可见的枚举,但这是可配置的。
规则说明
像其他值类型一样,未初始化枚举的默认值为零。 无标志特性的枚举应定义值为零的成员,这样默认值即为该枚举的有效值。 根据情况将成员命名为“None”(或其他允许的名称之一)。 否则,将零赋给最常使用的成员。 默认情况下,如果未在声明中设置第一个枚举成员的值,则其值为零。
如果某个应用了 FlagsAttribute 的枚举定义一个值为零的成员,则该成员的名称应为“None”(或其他允许的名称之一),以指示枚举中尚未设置值。 将值为零的成员用于任何其他目的与使用 FlagsAttribute 存在冲突,因为 AND
和 OR
位运算符对成员没有意义。 这意味着,只应为一个成员分配零值。 如果有多个零值成员在标志特性的枚举中出现,对于不为零的成员,Enum.ToString()
将返回不正确的结果。
如何解决冲突
若要解决无标志特性枚举与此规则的冲突,请定义值为零的成员,这是一项非中断性变更。 对于定义零值成员的标志特性枚举,请将此成员命名为“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 |
允许 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 标记枚举