共用方式為


CA1062:驗證公用方法的引數

型別名稱

ValidateArgumentsOfPublicMethods

CheckId

CA1062

分類

Microsoft.Design

中斷變更

不中斷

原因

外部可見的方法會取它其中一個參考引數的值,而不驗證該引數是否是 null (在 Visual Basic 中是 Nothing)。

規則描述

應根據 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 (在 Visual Basic 中為Nothing)。 若要解決違規情形,請使用靜態 (在 Visual Basic 中為共用) 方法,檢查複製的物件是否為 Null。

在下列 Person 類別範例中,傳遞至Person 複製建構函式的 other 物件可能是 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 物件中尋找 PassThroughNonNull 方法中的 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
    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;
    }
}