CA1062 Walidacja argumentów metod publicznych

Właściwości Wartość
Identyfikator reguły CA1062
Tytuł Waliduj argumenty metod publicznych
Kategoria Projekt
Poprawka powodująca niezgodność lub niezgodność Niezgodność
Domyślnie włączone na platformie .NET 8 Nie.

Przyczyna

Zewnętrznie widoczna metoda wyłusza jeden z argumentów odwołania bez sprawdzania, czy ten argument to null (Nothing w Visual Basic).

Tę regułę można skonfigurować tak, aby wykluczyć niektóre typy i parametry z analizy. Można również wskazać metody weryfikacji sprawdzania wartości null.

Opis reguły

Wszystkie argumenty odwołania przekazywane do metod widocznych zewnętrznie powinny być sprawdzane względem nullelementu . W razie potrzeby wyrzuć ArgumentNullException argument , gdy argument ma wartość null.

Jeśli można wywołać metodę z nieznanego zestawu, ponieważ jest zadeklarowana jako publiczna lub chroniona, należy zweryfikować wszystkie parametry metody. Jeśli metoda ma być wywoływana tylko przez znane zestawy, oznacz metodę internal i zastosuj InternalsVisibleToAttribute atrybut do zestawu zawierającego metodę.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, zweryfikuj każdy argument odwołania względem nullelementu .

Kiedy pomijać ostrzeżenia

Jeśli masz pewność, że parametr wyłudzony został zweryfikowany przez inne wywołanie metody w funkcji, możesz pominąć ostrzeżenie z tej reguły.

Pomijanie ostrzeżenia

Jeśli chcesz po prostu pominąć pojedyncze naruszenie, dodaj dyrektywy preprocesora do pliku źródłowego, aby wyłączyć, a następnie ponownie włączyć regułę.

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

Aby wyłączyć regułę dla pliku, folderu lub projektu, ustaw jego ważność na none w pliku konfiguracji.

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

Aby uzyskać więcej informacji, zobacz Jak pominąć ostrzeżenia dotyczące analizy kodu.

Konfigurowanie kodu do analizowania

Użyj poniższych opcji, aby skonfigurować, które części bazy kodu mają być uruchamiane w tej regule.

Te opcje można skonfigurować tylko dla tej reguły, dla wszystkich reguł, których dotyczy, lub dla wszystkich reguł w tej kategorii (Projekt), do których ma ona zastosowanie. Aby uzyskać więcej informacji, zobacz Opcje konfiguracji reguły jakości kodu.

Uwzględnij określone powierzchnie interfejsu API

Możesz skonfigurować, na których częściach bazy kodu ma być uruchamiana ta reguła, na podstawie ich ułatwień dostępu. Aby na przykład określić, że reguła powinna być uruchamiana tylko na powierzchni niepublicznego interfejsu API, dodaj następującą parę klucz-wartość do pliku editorconfig w projekcie:

dotnet_code_quality.CAXXXX.api_surface = private, internal

Uwaga

Ta opcja jest obsługiwana tylko dla ca1062 na platformie .NET 7 i nowszych wersjach.

Wykluczanie określonych symboli

Z analizy można wykluczyć określone symbole, takie jak typy i metody. Aby na przykład określić, że reguła nie powinna być uruchamiana w żadnym kodzie w typach o nazwie MyType, dodaj następującą parę klucz-wartość do pliku editorconfig w projekcie:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Dozwolone formaty nazw symboli w wartości opcji (oddzielone przez |):

  • Tylko nazwa symbolu (zawiera wszystkie symbole o nazwie, niezależnie od typu zawierającego lub przestrzeni nazw).
  • W pełni kwalifikowane nazwy w formacie identyfikatora dokumentacji symbolu. Każda nazwa symboli wymaga prefiksu typu symboli, takiego jak M: metody, T: dla typów i N: przestrzeni nazw.
  • .ctor dla konstruktorów i .cctor konstruktorów statycznych.

Przykłady:

Wartość opcji Podsumowanie
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Pasuje do wszystkich symboli o nazwie MyType.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Pasuje do wszystkich symboli o nazwie MyType1 lub MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Pasuje do określonej metody MyMethod z określonym w pełni kwalifikowanym podpisem.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Pasuje do określonych metod MyMethod1 i MyMethod2 z odpowiednimi w pełni kwalifikowanymi podpisami.

Wykluczanie określonych typów i ich typów pochodnych

Z analizy można wykluczyć określone typy i ich typy pochodne. Aby na przykład określić, że reguła nie powinna być uruchamiana na żadnych metodach w typach nazwanych MyType i ich typach pochodnych, dodaj następującą parę klucz-wartość do pliku .editorconfig w projekcie:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Dozwolone formaty nazw symboli w wartości opcji (oddzielone przez |):

  • Nazwa typu (zawiera tylko wszystkie typy o nazwie, niezależnie od typu zawierającego lub przestrzeni nazw).
  • W pełni kwalifikowane nazwy w formacie identyfikatora dokumentacji symbolu z opcjonalnym T: prefiksem.

Przykłady:

Wartość opcji Podsumowanie
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Pasuje do wszystkich typów nazwanych MyType i wszystkich ich typów pochodnych.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Dopasuje wszystkie typy o nazwie MyType1 lub MyType2 i wszystkie ich typy pochodne.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Pasuje do określonego typu MyType z daną w pełni kwalifikowaną nazwą i wszystkimi jego typami pochodnymi.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Pasuje do określonych typów MyType1 i MyType2 z odpowiednimi w pełni kwalifikowanymi nazwami i wszystkimi ich typami pochodnymi.

Wyklucz metodę rozszerzenia "this" parametru

Domyślnie ta reguła analizuje i flaguje this parametr dla metod rozszerzeń. Analizę parametru this dla metod rozszerzeń można wykluczyć, dodając następującą parę klucz-wartość do pliku .editorconfig w projekcie:

dotnet_code_quality.CA1062.exclude_extension_method_this_parameter = true

Metody sprawdzania wartości null

Ta reguła może prowadzić do fałszywie dodatnich, jeśli kod wywołuje specjalne metody sprawdzania wartości null w przywoływanych bibliotekach lub projektach. Tych wyników fałszywie dodatnich można uniknąć, określając nazwę lub podpis metod weryfikacji sprawdzania wartości null. Analiza zakłada, że argumenty przekazywane do tych metod są inne niż null po wywołaniu. Aby na przykład oznaczyć wszystkie metody o nazwie Validate null-check, dodaj następującą parę klucz-wartość do pliku .editorconfig w projekcie:

dotnet_code_quality.CA1062.null_check_validation_methods = Validate

Dozwolone formaty nazw metod w wartości opcji (oddzielone przez |):

  • Tylko nazwa metody (zawiera wszystkie metody o nazwie, niezależnie od typu zawierającego lub przestrzeni nazw).
  • W pełni kwalifikowane nazwy w formacie identyfikatora dokumentacji symbolu z opcjonalnym M: prefiksem.

Przykłady:

Wartość opcji Podsumowanie
dotnet_code_quality.CA1062.null_check_validation_methods = Validate Pasuje do wszystkich metod nazwanych Validate w kompilacji.
dotnet_code_quality.CA1062.null_check_validation_methods = Validate1|Validate2 Pasuje do wszystkich metod o nazwie Validate1 lub Validate2 w kompilacji.
dotnet_code_quality.CA1062.null_check_validation_methods = NS.MyType.Validate(ParamType) Pasuje do określonej metody Validate z podanym w pełni kwalifikowanym podpisem.
dotnet_code_quality.CA1062.null_check_validation_methods = NS1.MyType1.Validate1(ParamType)|NS2.MyType2.Validate2(ParamType) Pasuje do określonych metod Validate1 i Validate2 z odpowiednim w pełni kwalifikowanym podpisem.

Przykład 1

W poniższym przykładzie przedstawiono metodę, która narusza regułę i metodę spełniającą regułę.

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

Przykład 2

Konstruktory kopiujące, które wypełniają pola lub właściwości, które są obiektami referencyjnymi, mogą również naruszać regułę CA1062. Naruszenie występuje, ponieważ skopiowany obiekt przekazany do konstruktora kopiowania może mieć null wartość (Nothing w Visual Basic). Aby rozwiązać ten problem, użyj static metody (Shared w Visual Basic), aby sprawdzić, czy skopiowany obiekt nie ma wartości null.

W poniższym Person przykładzie other klasy obiekt przekazany do konstruktora kopiowania Person może mieć wartość 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)
    {
    }
}

Przykład 3

W poniższym poprawionym Person przykładzie other obiekt przekazany do konstruktora kopiowania jest najpierw sprawdzany pod kątem wartości null w metodzie 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;
    }
}