Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
| Propiedad | Value |
|---|---|
| Identificador de la regla | CA2208 |
| Título | Crear instancias de las excepciones del argumento correctamente |
| Categoría | Uso |
| La corrección es problemática o no problemática | Poco problemático |
| Habilitado de forma predeterminada en .NET 10 | Como sugerencia |
Causa
Cuando un método tiene un parámetro y produce un tipo de excepción ArgumentException o derivado de esta excepción, se espera que llame a un constructor que acepte un parámetro paramName correctamente. Estas son algunas de las causas posibles:
- Se realiza una llamada al constructor predeterminado (sin parámetros) de un tipo de excepción que es, o se deriva de , ArgumentException que también tiene un constructor que acepta un
paramNameparámetro. - Un argumento de cadena incorrecto se pasa a un constructor con parámetros de un tipo de excepción ArgumentException o derivado de esta excepción. Por ejemplo, el
paramNameargumento no coincide con el nombre de uno de los parámetros del método. - Se pasa un nombre de parámetro para el argumento
messagedel constructor de un tipo de excepción que es ArgumentException o se deriva de ArgumentException.
Descripción de la regla
En lugar de llamar al constructor predeterminado, llame a una de las sobrecargas del constructor que permite proporcionar un mensaje de excepción más significativo. El mensaje de excepción debe dirigirse al desarrollador y explicar claramente la condición de error y cómo corregir o evitar la excepción.
Las signaturas de los constructores de una y dos cadenas de ArgumentException y sus tipos derivados no son coherentes con respecto a los parámetros de posición message y paramName. Asegúrese de llamar a estos constructores con los argumentos de cadenas correctos. Las signaturas son las siguientes:
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)
Cómo corregir infracciones
Para corregir una infracción de esta regla, llame a un constructor que tome un mensaje, un nombre de parámetro o ambos, y asegúrese de que los argumentos sean correctos para el tipo de ArgumentException al que se está llamando.
Sugerencia
Hay una corrección de código en Visual Studio para los nombres de parámetros colocados incorrectamente. Para usarla, coloque el cursor sobre la fila de advertencia y presione Ctrl+. (periodo). Elija Intercambiar el orden de los argumentos en la lista de opciones que se presentan.
Si se pasa un nombre de parámetro en lugar de un mensaje al método ArgumentException(String), la corrección proporcionará la opción de cambiar al constructor de dos argumentos en su lugar.
Cuándo suprimir las advertencias
Es seguro suprimir una advertencia de esta regla solo si se llama a un constructor con parámetros con los argumentos de cadenas correctos.
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 CA2208
// The code that's violating the rule is on this line.
#pragma warning restore CA2208
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.CA2208.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 se ejecutará esta regla, en función de su accesibilidad, mediante la configuración de la opción api_surface. 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
Nota:
Reemplace la parte XXXX de CAXXXX por el identificador de la regla que sea de aplicación.
De forma predeterminada, la regla CA2208 se aplica a todas las superficies de API (públicas, internas y privadas).
Ejemplo
En el código siguiente se muestra un constructor que crea incorrectamente una instancia de 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
En el código siguiente se corrige la infracción anterior cambiando los argumentos del constructor.
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
El siguiente código muestra un método que lanza ArgumentNullException incorrectamente con un paramName que no coincide con ninguno de los parámetros del método. La regla se activa porque description es una variable local, no un parámetro del método.
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
En el código siguiente se corrige la infracción anterior mediante InvalidOperationException en su lugar, que es adecuada cuando el estado de un objeto no es válido.
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