null 許容の警告を解決する

この記事では、次のコンパイラの警告について説明します。

  • CS8597 - スローされた値が null である可能性があります。
  • CS8600 - Null リテラルまたは Null の可能性がある値を Null 非許容型に変換しています。
  • CS8601 - null 参照代入の可能性があります。
  • CS8602 - null 参照の可能性があるものの逆参照です。
  • CS8603 - null 参照戻り値である可能性があります。
  • CS8604 - パラメーターに null 参照引数がある可能性があります。
  • CS8605 - null の可能性がある値をボックス化解除しています。
  • CS8607 - [NotNull] または [DisallowNull] でマークされた型には null 値を使用できない可能性があります
  • CS8608 - 型における参照型の Null 許容性が、オーバーライドされるメンバーと一致しません。
  • CS8609 - 戻り値の型における参照型の Null 許容性が、オーバーライドされるメンバーと一致しません。
  • CS8610 - 型パラメーターにおける参照型の Null 許容性が、オーバーライドされるメンバーと一致しません。
  • CS8611 - 型パラメーターにおける参照型の Null 許容性が、部分メソッド宣言と一致しません。
  • CS8612 - 型における参照型の Null 許容性が、暗黙的に実装されるメンバーと一致しません。
  • CS8613 - 戻り値の型における参照型の Null 許容性が、暗黙的に実装されるメンバーと一致しません。
  • CS8614 - パラメーターの型における参照型の Null 許容性が、暗黙的に実装されるメンバーと一致しません。
  • CS8615 - 型における参照型の Null 許容性が、実装されるメンバーと一致しません。
  • CS8616 - 戻り値の型における参照型の Null 許容性が、実装されるメンバーと一致しません。
  • CS8617 - パラメーターの型における参照型の Null 許容性が、実装されるメンバーと一致しません。
  • CS8618 - null 非許容の変数には、コンストラクターの終了時に null 以外の値が入っていなければなりません。Null 許容として宣言することをご検討ください。
  • CS8619 - 値における参照型の Null 許容性が、対象の型と一致しません。
  • CS8620 - 参照型の NULL 値の許容の違いにより、パラメーターに引数を使用できません。
  • CS8621 - 戻り値の型における参照型の NULL 値の許容が、対象のデリゲートと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8622 - パラメーターの型における参照型の NULL 値の許容が、対象のデリゲートと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8624 - 参照型の NULL 値の許容の違いにより、引数を出力として使用することはできません。
  • CS8625 - null リテラルを null 非許容参照型に変換できません。
  • CS8629 - Null 許容値型は Null になる場合があります。
  • CS8631 - この型を、ジェネリック型またはメソッド内で型パラメーターとして使用することはできません。型引数の Null 許容性が制約型と一致しません。
  • CS8633 - メソッドの型パラメーターに対する制約の Null 許容性が、インターフェイス メソッドの型パラメーターに対する制約と一致しません。明示的なインターフェイスの実装を使用することをお勧めします。
  • CS8634 - この型を、ジェネリック型またはメソッド内で型パラメーターとして使用することはできません。型引数の Null 許容性が 'class' 制約と一致しません。
  • CS8643 - 明示的なインターフェイス指定子内の参照型の Null 許容性が、型によって実装されているインターフェイスと一致しません。
  • CS8644 - 型はインターフェイス メンバーを実装しません。基本型で実装されているインターフェイス内の参照型の Null 許容性が一致しません。
  • CS8645 - メンバーは既に型のインターフェイス リストに存在しますが、参照型の Null 許容性が異なっています。
  • CS8655 - switch 式が一部の null 入力を処理しません (すべてを網羅していません)。
  • CS8667 - 部分メソッド宣言には、型パラメーターの制約に NULL 値の許容の矛盾があります。
  • CS8670 - オブジェクトまたはコレクション初期化子が、null メンバーの可能性があるものを逆参照しています。
  • CS8714 - この型を、ジェネリック型またはメソッド内で型パラメーターとして使用することはできません。型引数の Null 許容性が 'notnull' 制約と一致しません。
  • CS8762 - 終了時にパラメーターには null 以外の値が含まれている必要があります。
  • CS8763 - [DoesNotReturn] とマークされたメソッドは戻ることができません。
  • CS8764 - 戻り値の型の NULL 値の許容が、オーバーライドされたメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8765 - パラメーターの型の NULL 値の許容が、オーバーライドされたメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8766 - 戻り値の型における参照型の NULL 値の許容が、暗黙的に実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8767 - パラメーターの型における参照型の NULL 値の許容が、暗黙的に実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8768 - 戻り値の型における参照型の NULL 値の許容が、実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8769 - パラメーターの型における参照型の NULL 値の許容が、実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8770 - メソッドには、実装またはオーバーライドされたメンバーに一致する [DoesNotReturn] 注釈がありません。
  • CS8774 - 終了時にメンバーには null 以外の値が含まれている必要があります。
  • CS8776 - この属性ではメンバーを使用できません。
  • CS8775 - 終了時にメンバーには null 以外の値が含まれている必要があります。
  • CS8777 - 終了時にパラメーターには null 以外の値が含まれている必要があります。
  • CS8819 - 戻り値の型における参照型の Null 値の許容が、部分メソッド宣言と一致しません。
  • CS8824 - パラメーターが null 以外であるため、パラメーターには、終了時に null 以外の値が含まれている必要があります。
  • CS8825 - パラメーターが null 以外であるため、戻り値は null 以外でなければなりません。
  • CS8847 - 一部の null 入力が switch 式で処理されません (すべてが網羅されてはいません)。ただし、'when' 句を含むパターンがこの値と一致する可能性があります。

Null 許容の警告の目的は、アプリケーション実行時に System.NullReferenceException がスローされる可能性を最小限に抑えることです。 この目標を達成するために、コンパイラではコードに null 参照の例外につながる可能性があるコンストラクトがあるときに、静的分析と問題の警告を使用します。 型の注釈と属性を適用することで、コンパイラにその静的分析のための情報を提供します。 これらの注釈と属性は、型の引数、パラメーター、メンバーの NULL 値の許容を表します。 この記事では、コンパイラの静的分析によって生成される Null 許容に関する警告に対処するさまざまな手法について説明します。 ここで説明する手法は、一般的な C# コード用です。 「Null 許容参照型の処理」にて、Null 許容参照型と Entity Framework Core を処理する方法を確認してください。

ほぼすべての警告を、次の 4 つの手法のいずれかを使用して対処します。

  • 必要な null チェックを追加する。
  • ? または ! Null 許容注釈を追加する。
  • null セマンティクスを記述する属性を追加する。
  • 変数を正しく初期化する。

null の逆参照の可能性

この一連の警告によって、null-statemaybe-null の変数を逆参照していると警告されます。 これらの警告は次のとおりです。

  • CS8602 - null 参照の可能性があるものの逆参照です。
  • CS8670 - オブジェクトまたはコレクション初期化子が、null メンバーの可能性があるものを逆参照しています。

次のコードは、上記の各警告の 1 つの例を示しています。

class Container
{
    public List<string>? States { get; set; }
}

internal void PossibleDereferenceNullExamples(string? message)
{
    Console.WriteLine(message.Length); // CS8602

    var c = new Container { States = { "Red", "Yellow", "Green" } }; // CS8670
}

上の例では、警告の理由は、Container である cStates プロパティに null 値を持つことができるためです。 null である可能性があるコレクションに新しい状態を割り当てると、警告が発生します。

これらの警告を削除するには、変数を逆参照する前にその変数の null-statenot-null に変更するためにコードを追加する必要があります。 コレクション初期化子の警告を見つけにくい場合があります。 初期化子で要素を追加するときに、コレクションが maybe-null であることがコンパイラによって検出されます。

多くの場合、変数を逆参照する前に変数が null でないこと確認することで、これらの警告を修正できます。 message パラメーターを逆参照する前に null チェックを追加する以下を検討してください。

void WriteMessageLength(string? message)
{
    if (message is not null)
    {
        Console.WriteLine(message.Length);
    }
    
}

次の例では、States のバッキング ストレージを初期化し、set アクセサーを削除します。 クラスのコンシューマーはコレクションの内容を変更でき、コレクションのストレージは決して null にはなりません。

class Container
{
    public List<string> States { get; } = new();
}

他のケースでこれらの警告を受け取るときは、誤検知である可能性があります。 null をテストするプライベート ユーティリティ メソッドがある場合があります。 そのメソッドによって null チェックが提供されることは、コンパイラでは判断できません。 プライベート ユーティリティ メソッド IsNotNull を使用する次の例を考えてみましょう。

public void WriteMessage(string? message)
{
    if (IsNotNull(message))
        Console.WriteLine(message.Length);
}

プロパティ message.Length を記述するときに、静的分析によって messagenull である可能性があると判定されるため、null を逆参照している可能性があることがコンパイラによって警告されます。 IsNotNull によって null チェックが提供されることはわかっている場合があり、true が返されるときは、messagenull-statenot-null であるはずです。 コンパイラにそれらの事実を伝える必要があります。 1 つは、null 免除演算子 ! を使用する方法です。 次のコードと一致するように、WriteLine ステートメントを変更できます。

Console.WriteLine(message!.Length);

null 免除演算子を使用すると、その式が ! が適用されていない場合は maybe-null であったとしても、not-null になります。 この例では、IsNotNull のシグネチャに属性を追加する解決策のほうが適切です。

private static bool IsNotNull([NotNullWhen(true)] object? obj) => obj != null;

メソッドで true が返されるときは、obj パラメーターに使用されている引数は not-null であるという情報が、System.Diagnostics.CodeAnalysis.NotNullWhenAttribute によってコンパイラに伝えられます。 メソッドで false が返されるとき、その引数にはそのメソッドが呼びされた前と同じ null-state があります。

ヒント

メソッドやプロパティが null-state に及ぼす影響を記述するために使用できる、一連の豊富な属性が用意されています。 それらの詳細については、Null 許容静的分析属性に関する言語参照の記事で確認できます。

maybe-null の変数の逆参照に関する警告を修正することには、次の 3 つのいずれかの手法が関与します。

  • 欠けている null チェックを追加する。
  • API に null 分析属性を追加して、コンパイラの null-state の静的分析に影響を与える。 メソッドを呼び出した後に戻り値または引数が maybe-null または not-null になるときが、これらの属性によってコンパイラに伝えられます。
  • 式に null 免除演算子 ! を適用して、状態を強制的に not-null にする。

Null 非許容参照に null が代入されている可能性

この一連の警告は、null 非許容の型の変数を、null-statemaybe-null の式に代入しようとしていることを警告します。 これらの警告は次のとおりです。

  • CS8597 - スローされた値が null である可能性があります。
  • CS8600 - Null リテラルまたは Null の可能性がある値を Null 非許容型に変換しています。
  • CS8601 - null 参照代入の可能性があります。
  • CS8603 - null 参照戻り値である可能性があります。
  • CS8604 - パラメーターに null 参照引数がある可能性があります。
  • CS8605 - null の可能性がある値をボックス化解除しています。
  • CS8625 - null リテラルを null 非許容参照型に変換できません。
  • CS8629 - Null 許容値型は Null になる場合があります。

Null 非許容の変数に maybe-null の式を代入しようとすると、コンパイラからこれらの警告が発せられます。 次に例を示します。

string? TryGetMessage(int id) => "";

string msg = TryGetMessage(42);  // Possible null assignment.

さまざまな警告は、代入、ボックス化解除の割り当て、return ステートメント、メソッドの引数、throw 式など、コードに関する詳細を提供することを示しています。

これらの警告に対処するために、3 つのいずれかのアクションを実行できます。 1 つは、? 注釈を追加して変数を Null 許容参照型にする方法です。 その変更によって、他の警告が発生する可能性があります。 変数を Null 非許容参照から Null 許容参照に変更することで、その既定の null-statenot-null から maybe-null に変わります。 コンパイラの静的分析によって、maybe-null である変数を逆参照しているインスタンスが検出される場合があります。

その他のアクションによって、代入の右側が not-null であるということがコンパイラに伝えられます。 次の例に示すように、右側の式には代入の前に null チェックを行うことができました。

string notNullMsg = TryGetMessage(42) ?? "Unknown message id: 42";

前の例は、メソッドの戻り値の代入を示します。 メソッドで null でない値が返されるときに指摘するよう、メソッド (プロパティ) に注釈を付けることができます。 多くの場合、入力引数が not-null のときに戻り値が not-null であることが System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute によって特定されます。 もう 1 つは、null 免除演算子 ! を右側に追加する方法です。

string msg = TryGetMessage(42)!;

maybe-null 式を not-null 変数に代入することに関する警告を修正することには、次の 4 つのいずれかの手法が関与します。

  • 代入の左側を Null 許容型に変更する。 このアクションによって、その変数を逆参照するときに、新しい警告が発生する可能性があります。
  • 代入の前に null チェックを指定する。
  • 代入の右側を生成する API に注釈を付ける。
  • null 免除演算子を代入の右側に追加する。

初期化されていない Null 非許容参照

この一連の警告は、null 非許容の型の変数を、null-statemaybe-null の式に代入しようとしていることを警告します。 これらの警告は次のとおりです。

  • CS8618 - null 非許容の変数には、コンストラクターの終了時に null 以外の値が入っていなければなりません。Null 許容として宣言することをご検討ください。
  • CS8762 - 終了時にパラメーターには null 以外の値が含まれている必要があります。

例として、次のクラスについて考えてみましょう。

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

FirstNameLastName はどちらも初期化が保証されていません。 このコードが新しい場合は、パブリック インターフェイスの変更を検討してください。 上の例は次のように書き直すことができます。

public class Person
{
    public Person(string first, string last)
    {
        FirstName = first;
        LastName = last;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

名前を設定する前に Person オブジェクトを作成する必要がある場合は、既定の null 以外の値を使用してプロパティを初期化できます。

public class Person
{
    public string FirstName { get; set; } = string.Empty;
    public string LastName { get; set; } = string.Empty;
}

もう 1 つは、それらのメンバーを Null 許容参照型に変更する方法です。 名前に null が許可される必要がある場合は、Person クラスを次のように定義できます。

public class Person
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
}

既存のコードでは、それらのメンバーの null セマンティクスについてコンパイラに通知するために、その他の変更が必要な場合があります。 複数のコンストラクターを作成したことで、クラスに 1 つ以上のメンバーを初期化するプライベート ヘルパー メソッドがある可能性があります。 初期化コードを 1 つのコンストラクターに移動し、すべてのコンストラクターから共通の初期化コードを含むものを呼び出すようにすることができます。 または、System.Diagnostics.CodeAnalysis.MemberNotNullAttribute 属性と System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute 属性を使用できます。 これらの属性によって、メソッドが呼び出された後にメンバーが "null でない" ことがコンパイラに伝えられます。 次のコードは、それぞれの例を示しています。 Person クラスでは、他のすべてのコンストラクターによって呼び出される共通のコンストラクターを使用しています。 Student クラスには、System.Diagnostics.CodeAnalysis.MemberNotNullAttribute 属性で注釈付けされたヘルパー メソッドがあります。


using System.Diagnostics.CodeAnalysis;

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public Person() : this("John", "Doe") { }
}

public class Student : Person
{
    public string Major { get; set; }

    public Student(string firstName, string lastName, string major)
        : base(firstName, lastName)
    {
        SetMajor(major);
    }

    public Student(string firstName, string lastName) :
        base(firstName, lastName)
    {
        SetMajor();
    }

    public Student()
    {
        SetMajor();
    }

    [MemberNotNull(nameof(Major))]
    private void SetMajor(string? major = default)
    {
        Major = major ?? "Undeclared";
    }
}

最後に、null 免除演算子を使用して、メンバーが他のコードで初期化されていることを示すことができます。 別の例として、Entity Framework Core モデルを表す次のクラスについて考えてみてください。

public class TodoItem
{
    public long Id { get; set; }
    public string? Name { get; set; }
    public bool IsComplete { get; set; }
}

public class TodoContext : DbContext
{
    public TodoContext(DbContextOptions<TodoContext> options)
        : base(options)
    {
    }

    public DbSet<TodoItem> TodoItems { get; set; } = null!;
}

DbSet プロパティは null! に初期化されます。 プロパティが not-null 値に設定されたことがコンパイラに伝えられます。 実際、ベースの DbContext によってそのセットの初期化が実行されます。 コンパイラの静的分析では、それを拾いません。 null 許容参照型と Entity Framework Core の処理の詳細については、「EF Core での Null 許容参照型の処理」の記事を参照してください。

Null 非許容メンバーの初期化に関する警告を修正することには、次の 4 つのいずれかの手法が関与します。

  • コンストラクターまたはフィールド初期化子を変更し、すべての Null 非許容メンバーが初期化されるようにする。
  • 1 つ以上のメンバーを Null 許容型に変更する。
  • ヘルパー メソッドに注釈を付け、どのメンバーが代入されているかを示す。
  • null! に初期化子を追加して、そのメンバーが他のコードで初期化されていることを示す。

NULL 値の許容の宣言の不一致

多くの警告では、メソッド、デリゲート、型パラメーターのシグネチャ間の NULL 値の許容不一致を示します。

  • CS8608 - 型における参照型の Null 許容性が、オーバーライドされるメンバーと一致しません。
  • CS8609 - 戻り値の型における参照型の Null 許容性が、オーバーライドされるメンバーと一致しません。
  • CS8610 - 型パラメーターにおける参照型の Null 許容性が、オーバーライドされるメンバーと一致しません。
  • CS8611 - 型パラメーターにおける参照型の Null 許容性が、部分メソッド宣言と一致しません。
  • CS8612 - 型における参照型の Null 許容性が、暗黙的に実装されるメンバーと一致しません。
  • CS8613 - 戻り値の型における参照型の Null 許容性が、暗黙的に実装されるメンバーと一致しません。
  • CS8614 - パラメーターの型における参照型の Null 許容性が、暗黙的に実装されるメンバーと一致しません。
  • CS8615 - 型における参照型の Null 許容性が、実装されるメンバーと一致しません。
  • CS8616 - 戻り値の型における参照型の Null 許容性が、実装されるメンバーと一致しません。
  • CS8617 - パラメーターの型における参照型の Null 許容性が、実装されるメンバーと一致しません。
  • CS8619 - 値における参照型の Null 許容性が、対象の型と一致しません。
  • CS8620 - 参照型の NULL 値の許容の違いにより、パラメーターに引数を使用できません。
  • CS8621 - 戻り値の型における参照型の NULL 値の許容が、対象のデリゲートと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8622 - パラメーターの型における参照型の NULL 値の許容が、対象のデリゲートと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8624 - 参照型の NULL 値の許容の違いにより、引数を出力として使用することはできません。
  • CS8631 - この型を、ジェネリック型またはメソッド内で型パラメーターとして使用することはできません。型引数の Null 許容性が制約型と一致しません。
  • CS8633 - メソッドの型パラメーターに対する制約の Null 許容性が、インターフェイス メソッドの型パラメーターに対する制約と一致しません。明示的なインターフェイスの実装を使用することをお勧めします。
  • CS8634 - この型を、ジェネリック型またはメソッド内で型パラメーターとして使用することはできません。型引数の Null 許容性が 'class' 制約と一致しません。
  • CS8643 - 明示的なインターフェイス指定子内の参照型の Null 許容性が、型によって実装されているインターフェイスと一致しません。
  • CS8644 - 型はインターフェイス メンバーを実装しません。基本型で実装されているインターフェイス内の参照型の Null 許容性が一致しません。
  • CS8645 - メンバーは既に型のインターフェイス リストに存在しますが、参照型の Null 許容性が異なっています。
  • CS8667 - 部分メソッド宣言には、型パラメーターの制約に NULL 値の許容の矛盾があります。
  • CS8714 - この型を、ジェネリック型またはメソッド内で型パラメーターとして使用することはできません。型引数の Null 許容性が 'notnull' 制約と一致しません。
  • CS8764 - 戻り値の型の NULL 値の許容が、オーバーライドされたメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8765 - パラメーターの型の NULL 値の許容が、オーバーライドされたメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8766 - 戻り値の型における参照型の NULL 値の許容が、暗黙的に実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8767 - パラメーターの型における参照型の NULL 値の許容が、暗黙的に実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8768 - 戻り値の型における参照型の NULL 値の許容が、実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8769 - パラメーターの型における参照型の NULL 値の許容が、実装されるメンバーと一致しません。おそらく、NULL 値の許容の属性が原因です。
  • CS8819 - 戻り値の型における参照型の Null 値の許容が、部分メソッド宣言と一致しません。

次のコードは CS8764 を示しています。

public class B
{
    public virtual string GetMessage(string id) => string.Empty;
}
public class D : B
{
    public override string? GetMessage(string? id) => default;
}

前の例は、ベース クラス内の virtual メソッドと、NULL 値の許容が異なる override を示します。 基本クラスでは Null 非許容文字列を返しますが、派生クラスでは Null 許容文字列を返します。 stringstring? が逆の場合は、派生クラスのほうがより制約があるため、許可されます。 同様に、パラメーターの宣言が一致する必要があります。 オーバーライド メソッドのパラメーターでは、基本クラスで許可されない場合でも null が許可されます。

他の状況では、これらの警告が生成される可能性があります。 インターフェイス メソッドの宣言と、そのメソッドの実装に不一致がある可能性があります。 または、デリゲート型と、そのデリゲートの式が異なる場合があります。 型パラメーターと型引数の NULL 値の許容が異なる場合があります。

これらの警告を修正するには、適切な宣言を更新します。

コードが属性宣言と一致しない

前のセクションでは、Null 許容静的分析の属性を使用して、コードの null セマンティクスについてコンパイラに伝える方法について説明しました。 コードがその属性の約束事に従わない場合、コンパイラから警告が発生します。

  • CS8607 - [NotNull] または [DisallowNull] でマークされた型には null 値を使用できない可能性があります
  • CS8763 - [DoesNotReturn] とマークされたメソッドは戻ることができません。
  • CS8770 - メソッドには、実装またはオーバーライドされたメンバーに一致する [DoesNotReturn] 注釈がありません。
  • CS8774 - 終了時にメンバーには null 以外の値が含まれている必要があります。
  • CS8775 - 終了時にメンバーには null 以外の値が含まれている必要があります。
  • CS8776 - この属性ではメンバーを使用できません。
  • CS8777 - 終了時にパラメーターには null 以外の値が含まれている必要があります。
  • CS8824 - パラメーターが null 以外であるため、パラメーターには、終了時に null 以外の値が含まれている必要があります。
  • CS8825 - パラメーターが null 以外であるため、戻り値は null 以外でなければなりません。

次の メソッドを考えてみましょう:

public bool TryGetMessage(int id, [NotNullWhen(true)] out string? message)
{
    message = null;
    return true;

}

message パラメーターに null が割り当てられ、"かつ" メソッドで true が返されるため、コンパイラで警告が発生します。 NotNullWhen 属性によって、それは発生しないはずであると指摘されます。

これらの警告に対処するには、適用した属性の期待と一致するようにコードを更新します。 属性またはアルゴリズムを変更できます。

網羅的な switch 式

switch 式は "網羅的" である必要があります。つまり、すべての入力値が処理される必要があります。 null 非許容の参照型の場合でも、null 値が考慮される必要があります。 null 値が処理されない場合、コンパイラの警告が発行されます。

  • CS8655 - switch 式が一部の null 入力を処理しません (すべてを網羅していません)。
  • CS8847 - 一部の null 入力が switch 式で処理されません (すべてが網羅されてはいません)。ただし、'when' 句を含むパターンがこの値と一致する可能性があります。

次のサンプル コードは、この条件を示しています。

int AsScale(string status) =>
    status switch
    {
        "Red" => 0,
        "Yellow" => 5,
        "Green" => 10,
        { } => -1
    };

入力式は string ですが、string? ではありません。 やはりコンパイラでこの警告が生成されます。 { } パターンは null 以外のすべての値を処理しますが、null に一致しません。 これらのエラーに対処するには、明示的な null ケースを追加するか、{ }_ (破棄) パターンに置き換えます。 破棄パターンは、null および他の任意の値に一致します。