CA1062: Validar argumentos de métodos públicos

Propiedad Value
Identificador de la regla CA1062
Título Validar argumentos de métodos públicos
Categoría Diseño
La corrección es problemática o no problemática Poco problemático
Habilitado de forma predeterminada en .NET 8 No

Causa

Un método visible externamente desreferencia uno de sus argumentos de referencia sin comprobar si ese argumento es null (Nothing en Visual Basic).

Puede configurar esta regla para excluir del análisis determinados tipos y parámetros. También puede indicar métodos de validación de comprobación de valores NULL.

Descripción de la regla

Es necesario comprobar todos los argumentos de referencia que se pasan a métodos visibles externamente para ver si son null. Si resulta adecuado, inicie una excepción ArgumentNullException cuando el argumento sea null.

Si se puede llamar a un método desde un ensamblado desconocido porque se ha declarado público o protegido, valide todos los parámetros del método. Si el método está diseñado para que solo lo llamen ensamblados conocidos, marque el método como internal y aplique el atributo InternalsVisibleToAttribute al ensamblado que contiene el método.

Cómo corregir infracciones

Para corregir una infracción de esta regla, valide cada argumento de referencia para ver si es null.

Cuándo suprimir las advertencias

Puede suprimir una advertencia de esta regla si está seguro de que el parámetro desreferenciado se ha validado mediante otra llamada de método en la función.

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 CA1062
// The code that's violating the rule is on this line.
#pragma warning restore CA1062

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.CA1062.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 las opciones siguientes para configurar en qué partes del código base se va a ejecutar esta regla.

Estas opciones pueden configurarse solo para esta regla, para todas las reglas a las que se aplican o para todas las reglas de esta categoría (Diseño) a las que se aplican. 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 ejecutar esta regla, en función de su accesibilidad. 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

Esta opción solo se admite en CA1062 en .NET 7 y versiones posteriores.

Exclusión de símbolos específicos

Puede excluir símbolos específicos, como tipos y métodos, del análisis. Por ejemplo, para especificar que la regla no se debe ejecutar en ningún código dentro de los tipos con el nombre MyType, agregue el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Formatos de nombre de símbolo permitidos en el valor de opción (separados por |):

  • Solo nombre de símbolo (incluye todos los símbolos con el nombre, con independencia del tipo contenedor o el espacio de nombres).
  • Nombres completos en el formato de id. de documentación del símbolo. Cada nombre de símbolo necesita un prefijo de tipo símbolo, como M: para los métodos, T: para los tipos y N: para los espacios de nombres.
  • .ctor para los constructores y .cctor para los constructores estáticos.

Ejemplos:

Valor de la opción Resumen
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Coincide con todos los símbolos denominados MyType.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Coincide con todos los símbolos denominados MyType1 o MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Coincide con un método MyMethod concreto con la signatura completa especificada.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Coincide con los métodos MyMethod1 y MyMethod2 concretos con las signaturas completas especificadas.

Exclusión de tipos específicos y sus tipos derivados

Puede excluir tipos específicos y sus tipos derivados del análisis. Por ejemplo, para especificar que la regla no se debe ejecutar en ningún método dentro de los tipos con el nombre MyType y sus tipos derivados, agregue el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Formatos de nombre de símbolo permitidos en el valor de opción (separados por |):

  • Solo nombre de tipo (incluye todos los tipos con el nombre, con independencia del tipo contenedor o el espacio de nombres).
  • Nombres completos en el formato de identificador de documentación del símbolo, con un prefijo T: opcional.

Ejemplos:

Valor de la opción Resumen
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Coincide con todos los tipos denominados MyType y todos sus tipos derivados.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Coincide con todos los tipos denominados MyType1 o MyType2, y todos sus tipos derivados.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Coincide con un tipo MyType específico con el nombre completo dado y todos sus tipos derivados.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Coincide con los tipos MyType1 y MyType2 específicos con los correspondientes nombres completos y todos sus tipos derivados.

Exclusión del parámetro "this" del método de extensión

De forma predeterminada, esta regla analiza y marca el parámetro this para los métodos de extensión. Puede excluir el análisis del parámetro this de los métodos de extensión si agrega el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CA1062.exclude_extension_method_this_parameter = true

Métodos de validación de comprobación de valores NULL

Esta regla puede producir falsos positivos si el código llama a métodos de validación de comprobación de valores NULL especiales en los proyectos o bibliotecas a los que se hace referencia. Puede evitar estos falsos positivos si especifica el nombre o la firma de los métodos de validación de comprobación de valores NULL. El análisis da por supuesto que los argumentos que se pasan a estos métodos no son NULL después de la llamada. Por ejemplo, para marcar todos los métodos denominados Validate como métodos de validación de comprobación de valores NULL, agregue el siguiente par clave-valor a un archivo .editorconfig en el proyecto:

dotnet_code_quality.CA1062.null_check_validation_methods = Validate

Formatos de nombre de método permitidos en el valor de opción (separados por |):

  • Solo nombre de método (incluye todos los métodos con el nombre, con independencia del tipo contenedor o el espacio de nombres).
  • Nombres completos en el formato de identificador de documentación del símbolo, con un prefijo M: opcional.

Ejemplos:

Valor de la opción Resumen
dotnet_code_quality.CA1062.null_check_validation_methods = Validate Coincide con todos los métodos llamados Validate en la compilación.
dotnet_code_quality.CA1062.null_check_validation_methods = Validate1|Validate2 Coincide con todos los métodos llamados Validate1 o Validate2 en la compilación.
dotnet_code_quality.CA1062.null_check_validation_methods = NS.MyType.Validate(ParamType) Coincide con un método Validate concreto con la signatura completa especificada.
dotnet_code_quality.CA1062.null_check_validation_methods = NS1.MyType1.Validate1(ParamType)|NS2.MyType2.Validate2(ParamType) Coincide con los métodos Validate1 y Validate2 concretos con la signatura completa respectiva.

Ejemplo 1

En el ejemplo siguiente se muestra un método que infringe la regla y un método que la cumple.

using System;

namespace DesignLibrary
{
    public class Test
    {
        // This method violates the rule.
        public void DoNotValidate(string input)
        {
            if (input.Length != 0)
            {
                Console.WriteLine(input);
            }
        }

        // This method satisfies the rule.
        public void Validate(string input)
        {
            if (input == null)
            {
                throw new ArgumentNullException(nameof(input));
            }
            if (input.Length != 0)
            {
                Console.WriteLine(input);
            }
        }
    }
}
Imports System

Namespace DesignLibrary

    Public Class Test

        ' This method violates the rule.
        Sub DoNotValidate(ByVal input As String)

            If input.Length <> 0 Then
                Console.WriteLine(input)
            End If

        End Sub

        ' This method satisfies the rule.
        Sub Validate(ByVal input As String)

            If input Is Nothing Then
                Throw New ArgumentNullException(NameOf(input))
            End If

            If input.Length <> 0 Then
                Console.WriteLine(input)
            End If

        End Sub

    End Class

End Namespace

Ejemplo 2

Los constructores de copia que rellenan campos o propiedades que son objetos de referencia también pueden infringir la regla CA1062. La infracción se produce porque el objeto copiado que se pasa al constructor de copia podría ser null (Nothing en Visual Basic). Para resolver la infracción, use un método static (Shared en Visual Basic) para comprobar que el objeto copiado no es NULL.

En el siguiente ejemplo de la clase Person, el objeto other que se pasa al constructor de copia Person podría ser null.

public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    // Copy constructor CA1062 fires because other is dereferenced
    // without being checked for null
    public Person(Person other)
        : this(other.Name, other.Age)
    {
    }
}

Ejemplo 3

En el siguiente ejemplo de Person revisado, se comprueba primero en el método PassThroughNonNull si el objeto other que se pasa al constructor de copia es NULL.

public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    // Copy constructor
    public Person(Person other)
        : this(PassThroughNonNull(other).Name, other.Age)
    {
    }

    // Null check method
    private static Person PassThroughNonNull(Person person)
    {
        if (person == null)
            throw new ArgumentNullException(nameof(person));
        return person;
    }
}