Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
| Свойство | Значение |
|---|---|
| Идентификатор правила | CA2208 |
| Заголовок | Правильно создавайте экземпляры исключений аргументов |
| Категория | Использование |
| Исправление является критическим или не критическим | Не критическое |
| Включен по умолчанию в .NET 10 | Как предложение |
Причина
Если метод имеет параметр и создает тип исключения, который является ArgumentException или производным от него, ожидается вызов конструктора, корректно принимающего параметр paramName. Возможные причины ошибки:
- Вызов выполняется к конструктору по умолчанию (без параметров) типа исключения, который является производным или производным от него, который также имеет конструктор, ArgumentException
paramNameпринимаюющий параметр. - Неверный строковый аргумент передается в параметризованный конструктор типа исключения, который является ArgumentException или производным от него. Например,
paramNameаргумент не соответствует имени одного из параметров метода. - Имя параметра передается для
messageаргумента конструктора типа исключения, который является или происходит от ArgumentException.
Описание правила
Вместо вызова конструктора по умолчанию вызовите одну из перегрузок конструктора, которая позволяет предоставить более осмысленное сообщение об исключении. Сообщение об исключении должно ориентироваться на разработчика и ясно объяснять условие ошибки, а также способы исправить исключение или избежать его.
Сигнатуры конструкторов строк класса ArgumentException и производных типов не соответствуют положению параметров message и paramName. Убедитесь, что эти конструкторы вызываются с правильными строковыми аргументами. Эти сигнатуры представлены ниже:
ArgumentException(string message)ArgumentException(string message, string paramName)ArgumentNullException(string paramName)ArgumentNullException(string paramName, string message)ArgumentOutOfRangeException(string paramName)ArgumentOutOfRangeException(string paramName, string message)DuplicateWaitObjectException(string parameterName)DuplicateWaitObjectException(string parameterName, string message)
Устранение нарушений
Чтобы устранить нарушение этого правила, вызовите конструктор, принимающий сообщение, имя параметра или оба значения, и убедитесь, что аргументы являются подходящими для вызываемого типа ArgumentException.
Совет
В Visual Studio доступно исправление кода для неправильно позиционированных имен параметров. Чтобы использовать его, поместите курсор в строку предупреждения и нажмите клавиши CTRL+ (период). Выберите Переключить порядок аргументов в списке.
Если в метод ArgumentException(String) передается имя параметра, а не сообщение, исправление предоставляет параметр для переключения на конструктор с двумя аргументами.
Когда лучше отключить предупреждения
Предупреждение для этого правила можно отключить, только если параметризованный конструктор вызывается с правильными строковыми аргументами.
Отключение предупреждений
Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.
#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_surface. Например, чтобы указать, что правило должно выполняться только для закрытой контактной зоны API, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:
dotnet_code_quality.CAXXXX.api_surface = private, internal
Заметка
Замените XXXX частью CAXXXX идентификатором применимого правила.
По умолчанию правило 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
В следующем коде показан метод, который неправильно вызывает ArgumentNullException, где paramName не соответствует ни одному из параметров метода. Правило запускается, так как description это локальная переменная, а не параметр метода.
public class Product
{
public string? Description { get; set; }
public string Name { get; set; } = string.Empty;
}
public class Example
{
// Violates CA2208: 'description' is not a parameter of this method.
public void ProcessProduct(Product product)
{
string? description = product.Description;
if (description is null)
{
throw new ArgumentNullException(nameof(description), $"Product named {product.Name} had no description!");
}
// Process description...
}
}
Public Class Product
Public Property Description As String
Public Property Name As String = String.Empty
End Class
Public Class Example
' Violates CA2208: 'description' is not a parameter of this method.
Public Sub ProcessProduct(ByVal product As Product)
Dim description As String = product.Description
If description Is Nothing Then
Throw New ArgumentNullException(NameOf(description), $"Product named {product.Name} had no description!")
End If
' Process description...
End Sub
End Class
Следующий код исправляет предыдущее нарушение, используя InvalidOperationException вместо этого, который следует использовать, когда состояние объекта недействительно.
public class Product
{
public string? Description { get; set; }
public string Name { get; set; } = string.Empty;
}
public class Example
{
// Fixed: Use InvalidOperationException for invalid object state.
public void ProcessProduct(Product product)
{
string? description = product.Description;
if (description is null)
{
throw new InvalidOperationException($"Product named {product.Name} had no description!");
}
// Process description...
}
}
Public Class Product
Public Property Description As String
Public Property Name As String = String.Empty
End Class
Public Class Example
' Fixed: Use InvalidOperationException for invalid object state.
Public Sub ProcessProduct(ByVal product As Product)
Dim description As String = product.Description
If description Is Nothing Then
Throw New InvalidOperationException($"Product named {product.Name} had no description!")
End If
' Process description...
End Sub
End Class