! (null 免除) 演算子 (C# リファレンス)

単項の接尾辞 ! 演算子は null 免除 (または null 抑制) 演算子です。 Null 許容注釈コンテキストが有効な場合、null 免除演算子を使って、前の式のすべての Null 許容警告を抑制します。 単項の接頭辞 ! 演算子は、論理否定演算子です。 null 免除演算子は実行時には影響を与えません。 式の null 状態を変更することによって、コンパイラの静的フロー分析にのみ影響を与えます。 実行時に、式 x! は基になる式 x の結果に評価されます。

null 許容参照型の機能の詳細については、「null 許容参照型」を参照してください。

使用例

null 免除演算子のユース ケースの 1 つは、引数検証ロジックをテストすることです。 たとえば、次のクラスを考えてみます。

#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.Name コードに対して次の警告が生成されます: Warning CS8602: Dereference of a possibly null reference

IsValid メソッドを変更できる場合は、NotNullWhen 属性を使用して、メソッドによって true が返されたときに IsValid メソッドの引数を 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 免除演算子を使用する必要はありません。これは、if ステートメント内で pnull にできないことを把握するのに十分な情報がコンパイラに含まれているためです。 変数の null 状態に関する追加情報を提供するための属性の詳細については、null 予測を定義する属性を使用した API のアップグレードに関するページを参照してください。

C# 言語仕様

詳細については、null 許容参照型仕様の下書きの「null 免除演算子」セクションを参照してください。

関連項目