Поделиться через


CA1008: перечисляемые типы должны иметь нулевое значение

TypeName

EnumsShouldHaveZeroValue

CheckId

CA1008

Категория

Microsoft.Design

Критическое изменение

Не критическое – Если предлагается добавить значение None к перечислению без флага. Критическое – если предлагается переименовать или удалить какие-либо значения перечисления.

Причина

Перечисление без примененного 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

См. также

Ссылки

Enum