CA1008: Enums は 0 値を含んでいなければなりません
TypeName |
EnumsShouldHaveZeroValue |
CheckId |
CA1008 |
分類 |
Microsoft.Design |
互換性に影響する変更点 |
なし - フラグではない列挙型に値 None を追加するよう求められる場合。あり - すべての列挙値を名前変更または削除するよう求められる場合。 |
原因
FlagsAttribute が適用されていない列挙型で、ゼロ値を持つメンバーが定義されていません。または、FlagsAttribute が適用された列挙型でゼロ値を持つメンバーが定義されていますが、名前が "None" ではないか、列挙型で複数のゼロ値を持つメンバーが定義されています。
規則の説明
初期化されていない列挙型の既定値は、他の値型と同様に、ゼロです。フラグではない属性が付いた列挙型では、ゼロ値を持つメンバーを定義する必要があります。これは、既定値を有効な列挙値にするためです。必要に応じてメンバーに "None" と名前を付けます。それ以外の場合、最もよく使用するメンバーにゼロを割り当てます。既定では、最初の列挙型メンバーの値が宣言で設定されない場合、値はゼロです。
FlagsAttribute を適用した列挙型でゼロ値のメンバーを定義する場合、名前を "None" にして、列挙型に設定済みの値がないことを示します。他の目的でゼロ値のメンバーを使用する方法は、FlagsAttribute を使用する方法 (メンバーで AND または OR のビット処理演算子を使用できません) とは正反対です。つまり、ゼロ値を割り当てるメンバーは 1 つのみにする必要があります。フラグの属性が付けられた列挙型でゼロ値を持つメンバーが複数存在する場合、ゼロ以外のメンバーに対して、Enum.ToString() から不適切な値が返されます。
違反の修正方法
フラグではない属性が付いた列挙型に関して、この規則違反を修正するには、ゼロ値を持つメンバーを定義します。これは互換性に影響する変更ではありません。ゼロ値のメンバーを定義するフラグの属性が付いた列挙型の場合、このメンバーに "None" という名前を付け、ゼロ値を持つメンバーが他にも存在する場合は削除します。これは互換性に影響する変更です。
警告を抑制する状況
以前に提供済みのフラグの属性が付いた列挙型の場合を除き、この規則からの警告を抑制しないでください。
使用例
規則に適合する 2 つの列挙型と、規則に違反する列挙型 BadTraceOptions を次の例に示します。
Imports System
Namespace DesignLibrary
Public Enum TraceLevel
Off = 0
AnError = 1
Warning = 2
Info = 3
Verbose = 4
End Enum
<Flags> _
Public Enum TraceOptions
None = 0
CallStack = &H01
LogicalStack = &H02
DateTime = &H04
Timestamp = &H08
End Enum
<Flags> _
Public Enum BadTraceOptions
CallStack = 0
LogicalStack = &H01
DateTime = &H02
Timestamp = &H04
End Enum
Class UseBadTraceOptions
Shared Sub Main()
' Set the flags.
Dim badOptions As BadTraceOptions = _
BadTraceOptions.LogicalStack Or BadTraceOptions.Timestamp
' Check whether CallStack is set.
If((badOptions And BadTraceOptions.CallStack) = _
BadTraceOptions.CallStack)
' This 'If' statement is always true.
End If
End Sub
End Class
End Namespace
using System;
namespace DesignLibrary
{
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 Main()
{
// 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.
}
}
}
}
using namespace System;
namespace DesignLibrary
{
public enum class TraceLevel
{
Off = 0,
Error = 1,
Warning = 2,
Info = 3,
Verbose = 4
};
[Flags]
public enum class TraceOptions
{
None = 0,
CallStack = 0x01,
LogicalStack = 0x02,
DateTime = 0x04,
Timestamp = 0x08
};
[Flags]
public enum class BadTraceOptions
{
CallStack = 0,
LogicalStack = 0x01,
DateTime = 0x02,
Timestamp = 0x04
};
}
using namespace DesignLibrary;
void main()
{
// Set the flags.
BadTraceOptions badOptions = safe_cast<BadTraceOptions>
(BadTraceOptions::LogicalStack | BadTraceOptions::Timestamp);
// Check whether CallStack is set.
if((badOptions & BadTraceOptions::CallStack) ==
BadTraceOptions::CallStack)
{
// This 'if' statement is always true.
}
}
関連規則
CA2217: enums を FlagsAttribute に設定しません
CA1700: enum 値に 'Reserved' という名前を指定しません
CA1712: enum 値を型名のプレフィックスにしません
CA1028: 列挙ストレージは Int32 でなければなりません
CA1027: FlagsAttribute で列挙値をマークします