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


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

Свойство Значение
Идентификатор правила CA1008
Заголовок Перечисляемые типы должны иметь нулевое значение
Категория Проектирование
Исправление является критическим или не критическим Не критическое — при появлении запроса на добавление значения None в перечисление без флага. Критическое — при появлении запроса на переименование или удаление любых значений перечисления.
Включен по умолчанию в .NET 8 No

Причина

Перечисление без применения System.FlagsAttribute не определяет элемент, имеющий нулевое значение. Или перечисление с применением FlagsAttribute определяет член, имеющий нулевое значение, но его имя не равно "None". Или перечисление определяет несколько элементов с нулевым значением.

По умолчанию это правило проверяет только видимые извне перечисления, но это поведение можно настроить.

Описание правила

Значение по умолчанию неинициализированного перечисления, как и других типов значений, равно нулю. Перечисление без флагов в качестве атрибутов должно определять элемент с использованием нулевого значения так, чтобы значение по умолчанию было допустимым значением перечисления. При необходимости назовите элемент None (или один из дополнительных разрешенных имен). В противном случае необходимо присвоить нулевое значение наиболее часто используемому элементу. По умолчанию, если значение первого элемента перечисления не задано в объявлении, его значение равно нулю.

Если перечисление, которое имеет FlagsAttribute примененный элемент, определяет нулевое значение члена, его имя должно быть "Нет" (или одно из дополнительных разрешенных имен), чтобы указать, что значения в перечислении не заданы. Использование элемента без значения для любой другой цели противоречит использованию FlagsAttribute операторов, которые AND побитовые OR операторы не используются с элементом. Это означает, что только одному элементу должно быть присвоено нулевое значение. Если несколько элементов с нулевым значением встречаются в перечислении с флагами, Enum.ToString() возвращает неверные результаты для элементов, которые не равны нулю.

Устранение нарушений

Чтобы устранить нарушение этого правила для перечислений без флагов, определите элемент, имеющий нулевое значение. Это некритическое изменение. Для перечислений с флагами, которые определяют элемент с нулевым значением, присвойте этому элементу имя "None" и удалите остальные элементы, имеющие нулевые значения. Это критическое изменение.

Когда лучше отключить предупреждения

Не отключайте предупреждение из этого правила, за исключением перечислений с флагами, которые были отправлены ранее.

Отключение предупреждений

Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.

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

Чтобы отключить правило для файла, папки или проекта, задайте его серьезность none в файле конфигурации.

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

Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.

Настройка кода для анализа

Используйте следующий параметр, чтобы выбрать части базы кода для применения этого правила.

Этот параметр можно настроить только для этого правила, для всех правил, к которым он применяется, или для всех правил в этой категории (конструкторе), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.

Включение определенных контактных зон API

Вы можете настроить, для каких частей базы кода следует выполнять это правило в зависимости от их доступности. Например, чтобы указать, что правило должно выполняться только для закрытой контактной зоны API, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Дополнительные имена полей нулевого значения

В .NET 7 и более поздних версиях можно настроить другие допустимые имена для поля перечисления нулевого значения, кроме Noneтого. Разделите несколько имен по символу | . В следующей таблице показаны некоторые примеры.

Значение параметра Итоги
dotnet_code_quality.CA1008.additional_enum_none_names = Never Разрешает оба None и Never
dotnet_code_quality.CA1008.additional_enum_none_names = Never|Nothing Разрешить None, Neverи Nothing

Пример

В следующем примере показаны два перечисления, которые удовлетворяют правилу, и перечисление BadTraceOptions, которое нарушает правило.

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

См. также