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
- Исключить определенные символы
- Исключить определенные типы и их производные типы
- Исключить параметр "this" метода расширения
- Методы проверки на значение NULL
Эти параметры можно настроить только для этого правила, для всех правил, к которым она применяется, или для всех правил в этой категории (конструкторе), к которым она применяется. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.
Включение определенных контактных зон 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
Допустимые форматы имени символа в значении параметра (разделенные |
):
- Только имя типа (включает все типы с этим именем, любого типа и в любом пространстве имен).
- полные имена в формате идентификатора документации для символа с необязательным префиксом
T:
.
Примеры:
Значение параметра | Итоги |
---|---|
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 |
Соответствует всем методам с именем или Validate1 Validate2 в компиляции. |
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;
}
}