CA1008: Las enumeraciones deben tener un valor igual a cero

Propiedad Value
Identificador de la regla CA1008
Título Las enumeraciones deben tener un valor igual a cero
Categoría Diseño
La corrección es problemática o no problemática No problemática: si se le pide agregar un valor None a una enumeración no marcada. Problemática: si se le pide cambiar el nombre o quitar valores de enumeración.
Habilitado de forma predeterminada en .NET 8 No

Causa

Una enumeración sin un elemento System.FlagsAttribute aplicado no define ningún miembro que tenga un valor de cero. O bien, una enumeración que tiene un aplicado un elemento FlagsAttribute define un miembro que tiene un valor de cero, pero cuyo nombre es "None". O bien, la enumeración define varios miembros que tienen un valor de cero.

De forma predeterminada, esta regla solo examina las enumeraciones visibles externamente, pero es configurable.

Descripción de la regla

El valor predeterminado de una enumeración no inicializada, igual que los otros tipos de valor, es cero. Una enumeración con atributo y sin marcadores debería definir un miembro que tenga el valor de cero de modo que el valor predeterminado sea un valor válido de la enumeración. Si procede, asigne al miembro el nombre «Ninguno» (o uno de los nombres permitidos adicionales). De lo contrario, asigne cero al miembro que se use con más frecuencia. De forma predeterminada, si el valor del primer miembro de la enumeración no se establece en la declaración, su valor es cero.

Si una enumeración a la que se le haya aplicado el elemento FlagsAttribute define un miembro con valor cero, su nombre debe ser «Ninguno» (o uno si el adicional permitiese nombres ) para indicar que no se han establecido valores en la enumeración. El uso de un miembro con valor cero para cualquier otro propósito es contrario al uso de FlagsAttribute en que los operadores bit a bit AND y OR son inútiles con el miembro. Esto implica que solo un miembro debe tener asignado el valor cero. Si se producen varios miembros que tienen el valor cero en una enumeración con atributo y marcadores, Enum.ToString() devuelve resultados incorrectos para los miembros que no son cero.

Cómo corregir infracciones

Para corregir una infracción de esta regla en enumeraciones con atributo y sin marcadores, defina un miembro que tenga el valor cero; se trata de un cambio no disruptivo. En el caso de las enumeraciones con atributo y marcadores que definen un miembro con valor cero, asigne el nombre "None" a este miembro y elimine cualquier otro miembro que tenga un valor cero; se trata de un cambio importante.

Cuándo suprimir las advertencias

No suprima una advertencia de esta regla excepto en las enumeraciones con atributo y marcadores que se hayan enviado previamente.

Supresión de una advertencia

Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.

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

Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad en none del archivo de configuración.

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

Para obtener más información, consulte Procedimiento para suprimir advertencias de análisis de código.

Configuración del código para analizar

Use la opción siguiente para configurar en qué partes del código base ejecutar esta regla.

Puede configurar esta opción solo para esta regla, para todas las reglas a las que se aplica o para todas las reglas de esta categoría (Diseño) a las que se aplica. Para más información, vea Opciones de configuración de reglas de calidad de código.

Incluir superficies de API específicas

Puede configurar en qué partes del código base ejecutar esta regla, en función de su accesibilidad. Por ejemplo, para especificar que la regla solo se debe ejecutar en la superficie de API no públicas, agregue el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Nombres de campo de valor cero adicionales

En .NET 7 y versiones posteriores, puede configurar otros nombres permitidos para un campo de enumeración de valor cero, además de None. Separa varios nombres por el carácter |. En la tabla siguiente se proporcionan algunos ejemplos.

Valor de la opción Resumen
dotnet_code_quality.CA1008.additional_enum_none_names = Never Permite None y Never
dotnet_code_quality.CA1008.additional_enum_none_names = Never|Nothing Permite None, Nevery Nothing

Ejemplo

En el ejemplo siguiente se muestran dos enumeraciones que cumplen la regla y una enumeración, BadTraceOptions, que la infringe.

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

Consulte también