Поделиться через


CA1062: проверьте аргументы открытых методов

TypeName

ValidateArgumentsOfPublicMethods

CheckId

CA1062

Категория

Microsoft.Design

Критическое изменение

Не критическое

Причина

Видимый для внешнего кода методы выполняет разыменование одного из своих ссылочных аргументов, не проверяя его на равенство со значением null (Nothing в Visual Basic).

Описание правила

Все ссылочные аргументы, передаваемые в видимые для внешнего кода методы, должны проверяться на равенство значению null. Если это возможно, при равенстве аргумента значению null следует вызывать исключение ArgumentNullException.

Если метод может быть вызван из неизвестной сборки, поскольку был объявлен как открытый или защищенный, необходимо проверить все параметры метода. Если метод сконструирован для вызова только известными сборками, следует сделать этот метод внутренним и применить атрибут InternalsVisibleToAttribute к сборке, содержащей этот метод.

Устранение нарушений

Чтобы устранить нарушение данного правила, проверьте каждый ссылочный аргумент на равенство значению null.

Отключение предупреждений

Предупреждение из этого правила можно отключить, если вы уверены, что со снятой ссылкой параметр был проверен другим вызовом метода в функции.

Пример

В следующем примере показан метод, который нарушает данное правило, и метод, удовлетворяющий ему.

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

В Visual Studio 2005 это правило не определяет ситуацию, когда параметры передаются другому методу, в котором производится такая проверка.

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

Конструкторы копирования, заполняющие поля или свойства, которые являются ссылочными объектами, также могут нарушать правило CA1062. Нарушение возникает, если копируемый объект, который передается в конструктор копирования, может иметь значение null (Nothing в Visual Basic). Чтобы устранить нарушение, используйте статический метод (Shared в Visual Basic), чтобы проверить, что скопированный объект не равен null.

В следующем примере класса Person объект other, который передается в конструктор копии Person, может быть равен 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)
    {
    }
}

В следующем пересмотренном примере класса Person объект other, который передается в конструктор копии, сначала проверяется на равенство NULL в методе 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;
    }
}