Compartir a través de


CA1062: Validar argumentos de métodos públicos

Nombre de tipo

ValidateArgumentsOfPublicMethods

Identificador de comprobación

CA1062

Categoría

Microsoft.Design

Cambio problemático

No

Motivo

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

Descripción de la regla

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

Si se puede llamar a un método desde un ensamblado desconocido porque se declara público o protegido, debería validar todos los parámetros del método.Si el método está diseñado para que sólo sea llamado por ensamblados conocidos, deberá convertir el método en interno y aplicar 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 con respecto a null.

Cuándo suprimir advertencias

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

Ejemplo

El ejemplo siguiente muestra un método que infringe la regla y un método que la cumple.

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("input")
            End If

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

        End Sub

    End Class

End Namespace
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)
    {
    }
}

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("input");
            }
            if (input.Length != 0)
            {
                Console.WriteLine(input);
            }
        }
    }
}

En Visual Studio 2005, esta regla no detecta que se están pasando parámetros a otro método que realiza la validación.

Public Function Method(ByVal value As String) As String
    EnsureNotNull(value)

    ' Fires incorrectly    
    Return value.ToString()
End Function

Private Sub EnsureNotNull(ByVal value As String)
    If value Is Nothing Then
        Throw (New ArgumentNullException("value"))
    End If
End Sub
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,
          PassThroughNonNull(other).Age)
    {
    }

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

public string Method(string value)
{
    EnsureNotNull(value);

    // Fires incorrectly    
    return value.ToString();
}

private void EnsureNotNull(string value)
{
    if (value == null)
        throw new ArgumentNullException("value");
}

Los constructores de copias que rellenan el campo o las 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 copias podría ser null (Nothing en Visual Basic).Para resolver la infracción, utilice 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 copias 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)
    {
    }
}

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

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, 
          PassThroughNonNull(other).Age)
    { 
    }

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