Compartir vía


CA2208: Crear instancias de las excepciones del argumento correctamente

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 paramName pará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 paramName argumento no coincide con el nombre de uno de los parámetros del método.
  • Se pasa un nombre de parámetro para el argumento message del 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:

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.

Corrección de código para CA2208 (intercambio de orden argumentos).

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.

Corrección de código para CA2208 (cambio al constructor de dos argumentos).

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