CA1008: перечисляемые типы должны иметь нулевое значение
TypeName |
EnumsShouldHaveZeroValue |
CheckId |
CA1008 |
Категория |
Microsoft.Design |
Критическое изменение |
Не критическое – Если предлагается добавить значение None к перечислению без флага. Критическое – если предлагается переименовать или удалить какие-либо значения перечисления. |
Причина
Перечисление без примененного System.FlagsAttribute не определяет член со значением равным нулю; или перечисление с примененным FlagsAttribute определяет член со значением равным нулю, но его имя не является "None", или перечисление определяет несколько членов со нулевым значением.
Описание правила
Значение по умолчанию неинициализированного перечисления, как и других типов значений, равно нулю. Перечисление с флагами в качестве атрибутов должно определять член с нулевым значением так, чтобы значение по умолчанию было допустимым значением перечисления. Если необходимо, присвойте члену имя "None". В противном случае присвойте ноль наиболее часто используемому члену. Обратите внимание, что если значение первого члена перечисления не задано в объявлении, его значение будет равно нулю по умолчанию.
Если перечисление с примененным FlagsAttribute определяет член с нулевым значением, его имя должно быть "None" для указания того, что значения не были заданы в перечислении. Использование члена с нулевым значением для любой другой цели противоположно использованию FlagsAttribute в том, что побитовые операторы AND и OR не имеют смысла для члена. Это предполагает, что нулевое значение должно быть назначено только одному члену. Обратите внимание, что если имеется несколько членов с нулевым значением в перечислении с флагами в качестве атрибутов, Enum.ToString() возвращает неверные результаты для членов, значение которых не равно нулю.
Устранение нарушений
Чтобы устранить нарушение этого правила для перечислений без флагов в качестве атрибутов, определите член с нулевым значением; это не будет критическим изменением. Для перечислений с флагами в качестве атрибутов, определяющих член с нулевым значением, назовите этот член "None" и удалите любые другие члены с нулевым значением – это будет критическое изменение.
Отключение предупреждений
Не отключайте предупреждение из этого правила, кроме как для перечислений с флагами в качестве атрибутов, которые были предоставлены ранее.
Пример
В приведенном ниже примере показано два перечисления, выполняющих правило, и перечисление 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: не следует помечать перечисления атрибутом FlagsAttribute
CA1700: не следует называть значения перечислений именем "Reserved"
CA1712: не добавляйте имя типа перед перечисляемыми значениями
CA1028: хранилище перечислений должно иметь тип Int32
CA1027: следует помечать перечисления атрибутом FlagsAttribute