CA2208: правильно создавайте экземпляры аргументов исключений

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

Причина

Если метод имеет параметр и создает тип исключения, который является ArgumentException или производным от него, ожидается вызов конструктора, корректно принимающего параметр paramName. Возможные причины ошибки:

  • Выполняется вызов конструктора по умолчанию (без параметров) для типа исключения, который является ArgumentException или производным от него и у которого есть конструктор, принимающий параметр paramName.

  • Неверный строковый аргумент передается в параметризованный конструктор типа исключения, который является ArgumentException или производным от него.

  • Одно из имен параметров передается в качестве аргумента message конструктора типа исключения, который является ArgumentException или производным от него.

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

Вместо вызова конструктора по умолчанию вызовите одну из перегрузок конструктора, которая позволяет предоставить более осмысленное сообщение об исключении. Сообщение об исключении должно ориентироваться на разработчика и ясно объяснять условие ошибки, а также способы исправить исключение или избежать его.

Сигнатуры конструкторов строк класса ArgumentException и производных типов не соответствуют положению параметров message и paramName. Убедитесь, что эти конструкторы вызываются с правильными строковыми аргументами. Эти сигнатуры представлены ниже:

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

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

Совет

В Visual Studio доступно исправление кода для неправильно позиционированных имен параметров. Чтобы использовать его, поместите курсор в строку предупреждения и нажмите клавиши CTRL+ (период). Выберите Переключить порядок аргументов в списке.

Code fix for CA2208 - swap arguments.

Если в метод ArgumentException(String) передается имя параметра, а не сообщение, исправление предоставляет параметр для переключения на конструктор с двумя аргументами.

Code fix for CA2208 - switch to two-argument constructor.

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

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

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

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

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

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

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

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

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

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

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

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

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

dotnet_code_quality.CAXXXX.api_surface = private, internal

По умолчанию правило CA2208 применяется ко всем областям API (общедоступные, внутренние и частные).

Пример

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

public class Book
{
    public Book(string title)
    {
        Title = title ??
            throw new ArgumentNullException("All books must have a title.", nameof(title));
    }

    public string Title { get; }
}
Public Class Book

    Private ReadOnly _Title As String

    Public Sub New(ByVal title As String)
        ' Violates this rule (constructor arguments are switched)            
        If (title Is Nothing) Then
            Throw New ArgumentNullException("title cannot be a null reference (Nothing in Visual Basic)", "title")
        End If
        _Title = title
    End Sub

    Public ReadOnly Property Title()
        Get
            Return _Title
        End Get
    End Property

End Class

Следующий код устраняет предыдущее нарушение, переключая аргументы конструктора.

public class Book
{
    public Book(string title)
    {
        Title = title ??
            throw new ArgumentNullException(nameof(title), "All books must have a title.");
    }

    public string Title { get; }
}
Public Class Book

    Private ReadOnly _Title As String

    Public Sub New(ByVal title As String)
        If (title Is Nothing) Then
            Throw New ArgumentNullException("title", "title cannot be a null reference (Nothing in Visual Basic)")
        End If

        _Title = title
    End Sub

    Public ReadOnly Property Title()
        Get
            Return _Title
        End Get
    End Property

End Class