Condividi tramite


CA1062: Convalidare gli argomenti di metodi pubblici

TypeName

ValidateArgumentsOfPublicMethods

CheckId

CA1062

Category

Microsoft.Design

Breaking Change

Non sostanziale

Causa

Un metodo visibile esternamente dereferenzia uno dei relativi argomenti di riferimento senza verificare se tale argomento è null (Nothing in Visual Basic).

Descrizione della regola

È necessario che tutti gli argomenti di riferimento che sono passati a metodi visibili esternamente vengano sottoposti a verifica per accertarsi che non corrispondano a valori null. Se possibile, quando l'argomento è null, verrà generata un'eccezione ArgumentNullException.

Se è possibile chiamare un metodo da un assembly sconosciuto perché viene dichiarato pubblico o protetto, è necessario convalidare tutti i parametri del metodo. Se il metodo viene progettato per essere chiamato solo dagli assembly noti, è necessario rendere interno il metodo e applicare l'attributo InternalsVisibleToAttribute all'assembly che contiene il metodo.

Come correggere le violazioni

Per correggere una violazione di questa regola, convalidare ciascun argomento di riferimento per accertarsi che non sia null.

Esclusione di avvisi

È possibile eliminare un avviso da questa regola se il parametro dereferenziato è stato convalidato da un'altra chiamata al metodo nella funzione.

Esempio

Nell'esempio riportato di seguito viene illustrato un metodo che viola la regola e un metodo che la soddisfa.

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);
            }
        }
    }
}

In Visual Studio 2005, questa regola non consente di rilevare che i parametri vengono passati a un altro metodo che esegue la convalida.

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");
}

Costruttori di copia che popolano campo o proprietà che sono oggetti di riferimento possono violare anche la regola CA1062. La violazione si verifica perché l'oggetto copiato che viene passato al costruttore di copia potrebbe essere null (Nothing in Visual Basic). Per risolvere la violazione, utilizzare un metodo statico (Condiviso in Visual Basic) per controllare che l'oggetto copiato non è null.

Nel seguente esempio di classe Person, l'oggetto other che viene passato al costruttore di copia Person potrebbe essere 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)
    {
    }
}

Nel seguente esempio di Person modificato, per l'oggetto other passato al costruttore di copia, viene in primo luogo controllata la presenza di valori null nel metodo 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;
    }
}