CA1008:Enums は 0 値を含んでいなければなりません
プロパティ | 値 |
---|---|
ルール ID | CA1008 |
Title | Enums は 0 値を含んでいなければなりません |
[カテゴリ] | デザイン |
修正が中断ありか中断なしか | 中断なし - フラグ以外の列挙型に None 値を追加するように求めるメッセージが表示された場合。 中断あり - 列挙型の値の名前変更または削除を求めるメッセージが表示された場合。 |
.NET 9 では既定で有効 | いいえ |
原因
System.FlagsAttribute が適用されていない列挙型では、値が 0 であるメンバーは定義されません。 または、FlagsAttribute が適用されている列挙型では、値は 0 であるが、その名前は 'None' ではないメンバーが定義されます。 または、列挙型では、0 値のメンバーが複数定義されます。
既定では、この規則の対象は外部から参照できる列挙型のみですが、これは構成可能です。
規則の説明
初期化されていない列挙型の既定値は、他の値型と同様に 0 です。 非フラグ属性付きの列挙型では、値が 0 であるメンバーを定義する必要があります。これは、既定値を有効な列挙型の値にするためです。 必要に応じて、メンバーの名前を 'None' (または許可されている追加の名前のいずれか) にします。 それ以外の場合は、最も頻繁に使用されるメンバーに 0 を割り当てます。 既定では、最初の列挙型メンバーの値が宣言内に設定されていない場合、その値は 0 になります。
FlagsAttribute を適用した列挙型で 0 値のメンバーを定義する場合は、その名前を "None" (あるいは、許可されている追加の名前のいずれか) にして、列挙型に設定済みの値がないことを示す必要があります。 他の目的で 0 値のメンバーを使用することは、FlagsAttribute および AND
のビット単位の演算子がメンバーに対して役に立たないという点で、OR
の使用に反しています。 これは 1 つのメンバーにのみ値 0 を割り当てる必要があることを意味します。 値が 0 である複数のメンバーがフラグ属性付きの列挙型で検出された場合、Enum.ToString()
からは、0 でないメンバーに対して正しくない結果が返されます。
違反の修正方法
非フラグ属性付き列挙型について、この規則違反を修正するには、値が 0 であるメンバーを定義します。これは非破壊的変更です。 0 値のメンバーを定義するフラグ属性付き列挙型の場合、このメンバーに "None" という名前を付け、値が 0 の他のメンバーをすべて削除します。これは破壊的変更です。
どのようなときに警告を抑制するか
以前に出荷されたフラグ属性付きの列挙型の場合を除き、この規則からの警告を抑制しないでください。
警告を抑制する
単一の違反を抑制するだけの場合は、ソース ファイルにプリプロセッサ ディレクティブを追加して無効にしてから、規則をもう一度有効にします。
#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
以外で 0 値列挙フィールドに許可されるその他の名前を構成します。 複数の名前は |
文字で区切ります。 次の表に例を示します。
オプション値 | まとめ |
---|---|
dotnet_code_quality.CA1008.additional_enum_none_names = Never |
None と Never の両方を許可します |
dotnet_code_quality.CA1008.additional_enum_none_names = Never|Nothing |
None 、Never 、Nothing を許可します |
例
次の例では、規則に適合する 2 つの列挙型と、規則に違反する列挙型 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: enum 値に 'Reserved' という名前を指定しません
- CA1712:列挙型値を型名のプレフィックスにしません
- CA1028:列挙ストレージは Int32 でなければなりません
- CA1027:列挙型を FlagsAttribute に設定します
関連項目
.NET