! (null-forgiving) 運算子 (C# 參考)

一元後置 ! 運算子是 null-forgiving 或 null-suppression 運算子。 在已啟用 可為 Null 的注釋內容中,您可以使用 null 表示運算子來隱藏上述運算式的所有可為 Null 警告。 一元前置 ! 詞運算子是 邏輯否定運算子。 null 表示運算子在執行時間沒有作用。 它只會藉由變更運算式的 Null 狀態來影響編譯器的靜態流程分析。 在執行時間,運算式 x! 會評估為基礎運算式 x 的結果。

如需可為 Null 參考型別功能的詳細資訊,請參閱 可為 Null 的參考型別

範例

Null 表示運算子的其中一個使用案例是測試引數驗證邏輯。 例如,請參考下列類別:

#nullable enable
public class Person
{
    public Person(string name) => Name = name ?? throw new ArgumentNullException(nameof(name));

    public string Name { get; }
}

您可以使用 MSTest 測試架構,為建構函式中的驗證邏輯建立下列測試:

[TestMethod, ExpectedException(typeof(ArgumentNullException))]
public void NullNameShouldThrowTest()
{
    var person = new Person(null!);
}

如果沒有 null 表示運算子,編譯器會產生上述程式碼的下列警告: Warning CS8625: Cannot convert null literal to non-nullable reference type 。 藉由使用 null 表示運算子,您會通知編譯器預期傳遞 null ,不應警告。

當您確定知道運算式不能, null 但編譯器無法辨識該運算式時,也可以使用 null 表示表示運算子。 在下列範例中,如果 IsValid 方法傳 true 回 ,則其引數不是 null ,而且您可以安全地取值它:

public static void Main()
{
    Person? p = Find("John");
    if (IsValid(p))
    {
        Console.WriteLine($"Found {p!.Name}");
    }
}

public static bool IsValid(Person? person)
    => person is not null && person.Name is not null;

如果沒有 null 表示運算子,編譯器會產生下列程式碼警告 p.NameWarning CS8602: Dereference of a possibly null reference

如果可以修改 IsValid 方法,您可以使用NotNullWhen屬性來通知編譯器方法的引數 IsValid 在方法傳回 true 時不能是 null

public static void Main()
{
    Person? p = Find("John");
    if (IsValid(p))
    {
        Console.WriteLine($"Found {p.Name}");
    }
}

public static bool IsValid([NotNullWhen(true)] Person? person)
    => person is not null && person.Name is not null;

在上述範例中,您不需要使用 null 表示運算子,因為編譯器有足夠的資訊可找出 p 不能在 null 語句內 if 。 如需屬性的詳細資訊,這些屬性可讓您提供變數 Null 狀態的其他資訊,請參閱 使用屬性升級 API 以定義 Null 期望

C# 語言規格

如需詳細資訊,請參閱可為 Null 參考型別規格草稿的null-forgiving 運算子一節。

另請參閱