Freigeben über


CA1062: Argumente von öffentlichen Methoden validieren

TypeName

ValidateArgumentsOfPublicMethods

CheckId

CA1062

Kategorie

Microsoft.Design

Unterbrechende Änderung

Nicht unterbrechend

Ursache

Eine extern sichtbare Methode dereferenziert eines der Verweisargumente, ohne zu überprüfen, ob das Argument null ist (Nothing in Visual Basic).

Regelbeschreibung

Alle an extern sichtbare Methoden übergebenen Verweisargumente sollten auf null überprüft werden. Es sollte ggf. eine ArgumentNullException ausgelöst werden, wenn das Argument null ist.

Wenn eine Methode von einer unbekannten Assembly aufgerufen werden kann, da sie als öffentlich oder geschützt deklariert wird, sollten Sie alle Parameter der Methode überprüfen. Wenn die Methode entworfen wird, um nur von bekannten Assemblys aufgerufen zu werden, sollten Sie die Methode intern machen und das InternalsVisibleToAttribute-Attribut für die Assembly übernehmen, die die Methode enthält.

Behandeln von Verstößen

Um einen Verstoß gegen diese Regel zu korrigieren, überprüfen Sie jedes Verweisargument auf null.

Wann sollten Warnungen unterdrückt werden?

Sie können eine Warnung von dieser Regel unterdrücken, wenn Sie sicher sind, dass der dereferenzierte Parameter von einem anderen Methodenaufruf in der Funktion überprüft wurde.

Beispiel

Das folgende Beispiel zeigt eine Methode, die gegen die Regel verstößt, und eine Methode, die der Regel entspricht.

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 erkennt diese Regel nicht, dass Parameter an eine andere Methode übergeben werden, die die Validierung ausführt.

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

Kopierkonstruktoren, die Felder oder Eigenschaften auffüllen, die Verweisobjekte sind, können auch gegen die CA1062-Regel verstoßen. Die Verletzung tritt auf, da das kopierte Objekt, das an den Kopierkonstruktor übergeben wird, null sein kann (Nothing in Visual Basic). Um die Verletzung zu beheben, verwenden Sie eine statische Methode (freigegeben in Visual Basic), um zu überprüfen, ob das kopierte Objekt nicht NULL ist.

Im folgenden Person-Klassenbeispiel könnte das other-Objekt, das an den Person-Kopierkonstruktor übergeben wird null sein.

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

Im folgenden überprüften Person-Klassenbeispiel wird das other-Objekt, das an den Kopierkonstruktor übergeben wird, zuerst auf Null in der PassThroughNonNull-Methode überprüft.

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