CA1008: Gli enum devono avere valore zero

Proprietà valore
ID regola CA1008
Title Le enumerazioni devono avere valore zero
Categoria Progettazione
Correzione che causa un'interruzione o un'interruzione Non di rilievo: quando viene richiesto di aggiungere un None valore a un'enumerazione non flag. Interruzione: quando viene richiesto di rinominare o rimuovere i valori di enumerazione.
Abilitato per impostazione predefinita in .NET 8 No

Causa

Un'enumerazione senza un oggetto applicato System.FlagsAttribute non definisce un membro con valore zero. In alternativa, un'enumerazione con un oggetto applicato FlagsAttribute definisce un membro con valore zero, ma il nome non è 'Nessuno'. In alternativa, l'enumerazione definisce più membri con valori zero.

Per impostazione predefinita, questa regola esamina solo enumerazioni visibili esternamente, ma è configurabile.

Descrizione regola

Il valore predefinito di un'enumerazione non inizializzata, proprio come altri tipi di valore, è zero. Un'enumerazione non con attributi flags deve definire un membro con il valore zero in modo che il valore predefinito sia un valore valido dell'enumerazione. Se appropriato, denominare il membro 'None' (o uno dei nomi consentiti aggiuntivi). In caso contrario, assegnare zero al membro usato più di frequente. Per impostazione predefinita, se il valore del primo membro di enumerazione non è impostato nella dichiarazione, il relativo valore è zero.

Se un'enumerazione con l'oggetto FlagsAttribute applicato definisce un membro con valori zero, il nome deve essere "None" (o uno dei nomi consentiti aggiuntivi) per indicare che nell'enumerazione non sono stati impostati valori. L'uso di un membro con valori zero per qualsiasi altro scopo è contrario all'uso di FlagsAttribute in in quanto gli AND operatori bit per bit e OR sono inutili con il membro. Ciò implica che a un solo membro deve essere assegnato il valore zero. Se più membri con valore zero si verificano in un'enumerazione con attributi flag, Enum.ToString() restituisce risultati non corretti per i membri che non sono zero.

Come correggere le violazioni

Per correggere una violazione di questa regola per enumerazioni non con attributi flags, definire un membro con il valore zero; si tratta di una modifica che non causa un'interruzione. Per le enumerazioni con attributi flag che definiscono un membro con valori zero, denominare questo membro 'Nessuno' ed eliminare tutti gli altri membri con valore zero; si tratta di una modifica che causa un'interruzione.

Quando eliminare gli avvisi

Non eliminare un avviso da questa regola, ad eccezione delle enumerazioni con attributi flag fornite in precedenza.

Eliminare un avviso

Se si vuole eliminare una singola violazione, aggiungere direttive del preprocessore al file di origine per disabilitare e quindi riabilitare la regola.

#pragma warning disable CA1008
// The code that's violating the rule is on this line.
#pragma warning restore CA1008

Per disabilitare la regola per un file, una cartella o un progetto, impostarne la gravità none su nel file di configurazione.

[*.{cs,vb}]
dotnet_diagnostic.CA1008.severity = none

Per altre informazioni, vedere Come eliminare gli avvisi di analisi del codice.

Configurare il codice da analizzare

Usare l'opzione seguente per configurare le parti della codebase in cui eseguire questa regola.

È possibile configurare questa opzione solo per questa regola, per tutte le regole a cui si applica o per tutte le regole in questa categoria (Progettazione) a cui si applica. Per altre informazioni, vedere Opzioni di configurazione delle regole di qualità del codice.

Includere superfici API specifiche

È possibile configurare le parti della codebase in modo da eseguire questa regola in base all'accessibilità. Ad esempio, per specificare che la regola deve essere eseguita solo sulla superficie dell'API non pubblica, aggiungere la coppia chiave-valore seguente a un file con estensione editorconfig nel progetto:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Altri nomi di campo con valore zero

In .NET 7 e versioni successive è possibile configurare altri nomi consentiti per un campo di enumerazione con valore zero, oltre Nonea . Separare più nomi in base al | carattere. La tabella seguente illustra alcuni esempi.

Valore opzione Riepilogo
dotnet_code_quality.CA1008.additional_enum_none_names = Never Consente sia che NoneNever
dotnet_code_quality.CA1008.additional_enum_none_names = Never|Nothing Consente None, Nevere Nothing

Esempio

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

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

Vedi anche