Gli enum devono avere valore zero

TypeName

EnumsShouldHaveZeroValue

CheckId

CA1008

Category

Microsoft.Design

Breaking Change

NonBreaking, Breaking

Causa

Un'enumerazione a cui non è applicato un attributo System.FlagsAttribute non definisce un membro con un valore zero oppure un'enumerazione a cui è applicato un attributo FlagsAttribute definisce un membro con un valore zero, ma il relativo nome non è "None" oppure l'enumerazione definisce più membri con valore zero.

Descrizione della regola

Il valore predefinito di un'enumerazione non inizializzata, come altri tipi di valore, è zero. Un'enumerazione senza attributi flag definisce un membro con il valore zero in modo che il valore predefinito sia un valore valido dell'enumerazione. Se appropriato, denominare il membro "None". In caso contrario, assegnare zero al membro più comunemente utilizzato. Si noti che se il valore del primo membro dell'enumerazione non è impostato nella dichiarazione, il relativo valore sarà zero per impostazione predefinita.

Se un'enumerazione a cui è applicato l'attributo FlagsAttribute definisce un membro con valore zero, il relativo nome deve essere "None" per indicare che nell'enumerazione non è stato impostato alcun valore. L'utilizzo di un membro con valore zero per altri scopi è contrario all'utilizzo dell'attributo FlagsAttribute in quanto gli operatori bit per bit AND e OR sono inutili con il membro. Il valore zero dovrà pertanto essere assegnato a un solo membro. Si noti che se sono presenti più membri con valore zero in un'enumerazione con attributi flag, Enum.ToString() restituirà risultati errati per i membri che non hanno valore zero.

Correzione di violazioni

Per correggere una violazione di questa regola per enumerazioni senza attributi flag, definire un membro con valore zero. Si tratta di una modifica non sostanziale. Per le enumerazioni con attributi flag che definiscono un membro con valore zero, denominare tale membro "None" ed eliminare qualsiasi altro membro con valore zero. Si tratta di una modifica sostanziale.

Esclusione di avvisi

Non escludere un avviso da questa regola se non per enumerazioni con attributi flag fornite in precedenza.

Esempio

Nell'esempio riportato di seguito vengono illustrate due enumerazioni che soddisfano la regola e un'enumerazione, BadTraceOptions, che la viola.

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.
   }
}

Regole correlate

Non contrassegnare le enumerazioni con FlagsAttribute

Non denominare 'Reserved' i valori di enumerazione

Non utilizzare nomi di tipo come prefisso nei valori di enumerazione

L'archivio di enum deve essere Int32

Sostituire gli enum con FlagsAttribute

Vedere anche

Riferimenti

System.Enum