共用方式為


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