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


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

Свойство Значение
Идентификатор правила CA1062
Заголовок Проверьте аргументы или открытые методы
Категория Проектирование
Исправление является критическим или не критическим Не критическое
Включен по умолчанию в .NET 8 No

Причина

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

Вы можете настроить это правило, чтобы исключить определенные типы и параметры из анализа. Вы также можете указать методы проверки на значение NULL.

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

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

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

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

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

Когда лучше отключить предупреждения

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

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

Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.

#pragma warning disable CA1062
// The code that's violating the rule is on this line.
#pragma warning restore CA1062

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

[*.{cs,vb}]
dotnet_diagnostic.CA1062.severity = none

Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.

Настройка кода для анализа

Используйте следующие параметры, чтобы указать части базы кода, к которым будет применяться это правило.

Эти параметры можно настроить только для этого правила, для всех правил, к которым она применяется, или для всех правил в этой категории (конструкторе), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.

Включение определенных контактных зон API

Вы можете настроить, для каких частей базы кода следует выполнять это правило в зависимости от их доступности. Например, чтобы указать, что правило должно выполняться только для закрытой контактной зоны API, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Примечание.

Этот параметр поддерживается только для CA1062 в .NET 7 и более поздних версиях.

Исключение определенных символов

Вы можете исключить из анализа определенные символы, например типы и методы. Например, чтобы указать, что правило не должно выполняться для какого-либо кода в типах с именем MyType, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Допустимые форматы имени символа в значении параметра (разделенные |):

  • Только имя символа (включает все символы с этим именем, любого типа и в любом пространстве имен).
  • Полные имена в формате идентификатора документации для символа. Для каждого имени символа требуется префикс в виде символа, например M: для методов, T: для типов и N: для пространств имен.
  • .ctor используется для конструкторов, а .cctor — для статических конструкторов.

Примеры:

Значение параметра Итоги
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Соответствует всем символам с именем MyType.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Соответствует всем символам с именем MyType1 или MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Соответствует конкретному методу MyMethod с заданной полной сигнатурой.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Соответствует конкретным методам MyMethod1 и MyMethod2 с соответствующими полными сигнатурами.

Исключить определенные типы и их производные типы

Из анализа можно исключать определенные типы и их производные типы. Например, чтобы указать, что правило не должно выполняться в каких-либо методах типов MyType и их производных типов, добавьте следующую пару "ключ-значение" в файл .editorconfig своего проекта:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Допустимые форматы имени символа в значении параметра (разделенные |):

Примеры:

Значение параметра Итоги
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Соответствует всем типам с именем MyType и всем их производным типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Соответствует всем типам с именем MyType1 или MyType2 и всем их производным типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Соответствует конкретному типу MyType с заданным полным именем и всем производным от него типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Соответствует конкретным типам MyType1 и MyType2 с заданным полным именем и всем производным от них типам.

Исключить параметр "this" метода расширения

По умолчанию это правило анализирует и помечает параметр this для методов расширения. Вы можете исключить анализ параметра this для методов расширения, добавив следующую пару "ключ-значение" в файл с расширением .editorconfig в своем проекте:

dotnet_code_quality.CA1062.exclude_extension_method_this_parameter = true

Методы проверки на значение NULL

Это правило может привести к ложноположительным результатам, если код вызывает специальные методы проверки на значения NULL в ссылочных библиотеках или проектах. Чтобы избежать этих ложноположительных результатов, можно указать имя или сигнатуру методов проверки на значение NULL. В анализе предполагается, что после вызова аргументы, передаваемые в эти методы, не имеют значение NULL. Например, чтобы пометить все методы с именами Validate как методы проверки на значения NULL, добавьте следующую пару "ключ-значение" в файл с расширением editorconfig в своем проекте:

dotnet_code_quality.CA1062.null_check_validation_methods = Validate

Допустимые форматы имени метода в значении параметра (разделенные |):

  • только имя метода (включает все методы с этим именем, независимо от типа и пространства имен);
  • полные имена в формате идентификатора документации для символа с необязательным префиксом M:.

Примеры:

Значение параметра Итоги
dotnet_code_quality.CA1062.null_check_validation_methods = Validate Соответствует всем методам, именованным Validate в компиляции.
dotnet_code_quality.CA1062.null_check_validation_methods = Validate1|Validate2 Соответствует всем методам с именем или Validate1Validate2 в компиляции.
dotnet_code_quality.CA1062.null_check_validation_methods = NS.MyType.Validate(ParamType) Соответствует конкретному методу Validate с заданной полной подписью.
dotnet_code_quality.CA1062.null_check_validation_methods = NS1.MyType1.Validate1(ParamType)|NS2.MyType2.Validate2(ParamType) Соответствует определенным методам Validate1 и Validate2 с соответствующей полной подписью.

Пример 1

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

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

Пример 2

Конструкторы копирования, заполняющие поля или свойства, которые являются ссылочными объектами, также могут нарушать правило CA1062. Нарушение возникает из-за того, что скопированный объект, переданный в конструктор копий, может иметь значение null (Nothing в Visual Basic). Чтобы устранить нарушение, используйте метод static (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)
    {
    }
}

Пример 3

В следующем исправленном примере 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, other.Age)
    {
    }

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