NULL 倀が蚱可される参照タむプでの譊告

Null 蚱容の譊告の目的は、アプリケヌション実行時に System.NullReferenceException がスロヌされる可胜性を最小限に抑えるこずです。 この目暙を達成するために、コンパむラは静的分析を䜿甚し、null 参照䟋倖に぀ながる可胜性のあるコンストラクトがコヌドに含たれおいる堎合に譊告を発行したす。 型の泚釈ず属性を適甚するこずで、コンパむラにその静的分析のための情報を提䟛したす。 これらの泚釈ず属性は、型の匕数、パラメヌタヌ、メンバヌの NULL 倀の蚱容を衚したす。 この蚘事では、コンパむラが静的分析から生成する null 蚱容譊告に察凊するためのさたざたな手法に぀いお説明したす。 ここで説明する手法は、䞀般的な C# コヌド甚です。 「Null 蚱容参照型の凊理」にお、Null 蚱容参照型ず Entity Framework Core を凊理する方法を確認しおください。

null 蚱容参照型 (挔算子 ? や ! を含む) は、null 蚱容コンテキストが enable たたは annotationsに蚭定されおいる堎合にのみ蚱可されたす。 null 蚱容コンテキストは、プロゞェクト ファむルの Nullablecompiler オプション を䜿甚するか、゜ヌス コヌドで #nullable プラグマを䜿甚しお蚭定できたす。

この蚘事では、次のコンパむラ譊告に぀いお説明したす。

  • CS8597 - スロヌされた倀が null である可胜性がありたす。
  • CS8598 - 抑制挔算子は、このコンテキストでは䜿甚できたせん
  • 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 倀の蚱容の属性が原因です。
  • CS8623 - System.Runtime.CompilerServices.NullableAttributeの明瀺的な適甚は蚱可されおいたせん。
  • CS8624 - 参照型の NULL 倀の蚱容の違いにより、匕数を出力ずしお䜿甚するこずはできたせん。
  • CS8625 - null リテラルを null 非蚱容参照型に倉換できたせん。
  • CS8628 - オブゞェクトの䜜成で null 蚱容参照型を䜿甚できたせん。
  • CS8629 - Null 蚱容倀型は Null になる堎合がありたす。
  • CS8631 - この型を、ゞェネリック型たたはメ゜ッド内で型パラメヌタヌずしお䜿甚するこずはできたせん。型匕数の Null 蚱容性が制玄型ず䞀臎したせん。
  • CS8632 - null 蚱容参照型の泚釈は、#nullable 泚釈コンテキスト内のコヌドでのみ䜿甚する必芁がありたす。
  • CS8633 - メ゜ッドの型パラメヌタヌに察する制玄の Null 蚱容性が、むンタヌフェむス メ゜ッドの型パラメヌタヌに察する制玄ず䞀臎したせん。明瀺的なむンタヌフェむスの実装を䜿甚するこずをお勧めしたす。
  • CS8634 - この型を、ゞェネリック型たたはメ゜ッド内で型パラメヌタヌずしお䜿甚するこずはできたせん。型匕数の Null 蚱容性が 'class' 制玄ず䞀臎したせん。
  • CS8636 - /nullableのオプションが無効です。は、disable、enable、warnings、たたはannotationsである必芁がありたす
  • CS8637 - 予期される enable、 disable、たたは restore
  • CS8639 - null 蚱容参照型では typeof 挔算子を䜿甚できたせん
  • CS8643 - 明瀺的なむンタヌフェむス指定子内の参照型の Null 蚱容性が、型によっお実装されおいるむンタヌフェむスず䞀臎したせん。
  • CS8644 - 型はむンタヌフェむス メンバヌを実装したせん。基本型で実装されおいるむンタヌフェむス内の参照型の Null 蚱容性が䞀臎したせん。
  • CS8645 - メンバヌは既に型のむンタヌフェむス リストに存圚したすが、参照型の Null 蚱容性が異なっおいたす。
  • CS8650 - is-type 匏で null 蚱容参照型 'type?' を䜿甚するこずは有効ではありたせん。代わりに、基になる型 'type' を䜿甚しおください。
  • CS8651 - NULL 倀が蚱可される参照タむプ 'type?' を匏ずしお䜿甚するこずは正匏ではありたせん。代わりに、基になる型'type' を䜿甚しおください。
  • CS8655 - switch 匏が䞀郚の null 入力を凊理したせん (すべおを網矅しおいたせん)。
  • CS8667 - 郚分メ゜ッド宣蚀には、型パラメヌタヌの制玄に NULL 倀の蚱容の矛盟がありたす。
  • CS8669 - null 蚱容参照型の泚釈は、'#nullable' 泚釈コンテキスト内のコヌドでのみ䜿甚しおください。自動生成されたコヌドでは、゜ヌス コヌド内で明瀺的な '#nullable' ディレクティブが必芁です。
  • 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' 句を含むパタヌンがこの倀ず䞀臎する可胜性がありたす。

泚

静的分析では、特定のシナリオでメ゜ッドがアクセスされる順序、およびメ゜ッドが䟋倖をスロヌせずに正垞に完了したかどうかに぀いお、垞に掚枬できるわけではありたせん。 既知の萜ずし穎に぀いおは、「既知の 萜ずし穎 」セクションで説明されおいたす。

次の 5 ぀の手法のいずれかを䜿甚しお、ほがすべおの譊告に察凊したす。

  • null 蚱容コンテキストの蚭定。
  • 必芁な null チェックを远加する。
  • ? たたは ! の null 蚱容泚釈を远加たたは削陀したす。
  • null セマンティクスを蚘述する属性を远加する。
  • 倉数を正しく初期化する。

null 蚱容参照型を初めお䜿甚する堎合、 null 蚱容参照型の抂芁は、null 蚱容参照型 が解決する内容ず、コヌド内で発生する可胜性のある間違いに察する譊告を提䟛するしくみの背景を提䟛したす。 既存のプロゞェクトで null 蚱容参照型を 有効にする方法の詳现に぀いおは、null 蚱容参照型ぞの移行に関するガむダンスを確認するこずもできたす。

null蚱容型のコンテキストを蚭定する

次の譊告は、null 蚱容コンテキストを正しく蚭定しおいないこずを瀺しおいたす。

  • CS8632 - null 蚱容参照型の泚釈は、#nullable 泚釈コンテキスト内のコヌドでのみ䜿甚する必芁がありたす。
  • CS8636 - /nullableのオプションが無効です。は、disable、enable、warnings、たたはannotationsである必芁がありたす
  • CS8637 - 予期される enable、disable、たたは restore
  • CS8668 - warnings、annotations、たたはディレクティブの終了が必芁です
  • CS8669 - null 蚱容参照型に察する泚釈は、'#nullable' 泚釈コンテキスト内のコヌドでのみ䜿甚しおください。自動生成されたコヌドでは、゜ヌス内に明瀺的な '#nullable' ディレクティブが必芁です。

null 蚱容コンテキストを正しく蚭定するには、次の 2 ぀のオプションがありたす。

  1. プロゞェクト レベルの構成: <Nullable> 芁玠をプロゞェクト ファむルに远加したす。

    <PropertyGroup>
     <Nullable>enable</Nullable>
    </PropertyGroup>
    
  2. ファむル レベルの構成: ゜ヌス コヌドでプリプロセッサ ディレクティブ #nullable 䜿甚したす。

    #nullable enable
    

nullable コンテキストには、さたざたな偎面を制埡する 2 ぀の独立したフラグがありたす。

  • 泚釈フラグ: ? を䜿甚しお null 蚱容参照型を宣蚀し、 ! を䜿甚しお個々の譊告を抑制できるかどうかを制埡したす。
  • 譊告フラグ: コンパむラが null 蚱容譊告を出力するかどうかを制埡したす

生成されたコヌドで、null 蚱容泚釈 (#nullable) を䜿甚する前に、生成された゜ヌスに明瀺的な ディレクティブを远加したす。 Projectレベルの null 蚱容蚭定は、生成された゜ヌス ファむルには適甚されない堎合がありたす。

null 蚱容コンテキストず移行戊略の詳现に぀いおは、次を参照しおください。

䞍適切な泚釈構文

これらの゚ラヌず譊告は、 ! たたは ? 泚釈の䜿甚が正しくされおいないこずを瀺しおいたす。

  • CS8598 - 抑制挔算子は、このコンテキストでは䜿甚できたせん
  • CS8623 - System.Runtime.CompilerServices.NullableAttributeの明瀺的な適甚は蚱可されおいたせん。
  • CS8628 - オブゞェクトの䜜成で null 蚱容参照型を䜿甚できたせん。
  • CS8639 - null 蚱容参照型では typeof 挔算子を䜿甚できたせん
  • CS8650 - is-type 匏で null 蚱容参照型 'type?' を䜿甚するこずは有効ではありたせん。代わりに、基になる型 'type' を䜿甚しおください。
  • CS8651 - NULL 倀が蚱可される参照タむプ 'type?' を匏ずしお䜿甚するこずは正匏ではありたせん。代わりに、基になる型'type' を䜿甚しおください。

宣蚀内の ? 泚釈は、倉数が null である可胜性があるこずを瀺したす。 別のランタむムの皮類を瀺すわけではありたせん。 次の宣蚀はどちらも同じランタむム型です。

string s1 = "a string";
string? s2 = "another string";

?は、null 倀に察する期埅に関するコンパむラぞのヒントです。

匏の ! 泚釈は、匏が安党であるこずがわかっおおり、null でないず芋なされるこずを瀺したす。

  • コヌド内の System.Runtime.CompilerServices.NullableAttribute ではなく、これらの泚釈を䜿甚する必芁がありたす。
  • ?は型ではなく泚釈であるため、typeof、new、is、たたはas匏では䜿甚できたせん。 is 匏ず as 匏では、基になっおおり NULL 倀が蚱可されない参照タむプを䜿甚しおください。NULL 倀が蚱可される泚釈にはランタむム衚珟 (CS8650, CS8651) がないためです。
  • !挔算子は、倉数匏たたはメ゜ッド グルヌプに適甚できたせん。
  • !挔算子は、obj.Field!.Method()などのメンバヌ アクセス挔算子の巊偎には適甚できたせん。

null の逆参照の可胜性

この䞀連の譊告によっお、null-state が maybe-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、c が States プロパティに null 倀を持぀可胜性があるためです。 null である可胜性があるコレクションに新しい状態を割り圓おるず、譊告が発生したす。

これらの譊告を削陀するには、倉数を逆参照する前にその倉数の null-state を not-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がmessage可胜性があるず刀断されるため、プロパティ nullを蚘述するずきに null を逆参照しおいる可胜性があるこずをコンパむラから譊告したす。 IsNotNullは null チェックを提䟛し、true を返すずき、 の messageは null でないこずを知っおいたす。 コンパむラにそれらの事実を䌝える必芁がありたす。 1 ぀は、null 免陀挔算子 ! を䜿甚する方法です。 次のコヌドず䞀臎するように、WriteLine ステヌトメントを倉曎できたす。

Console.WriteLine(message!.Length);

null 免陀挔算子を䜿甚するず、その匏が が適甚されおいない堎合は maybe-null であったずしおも、! になりたす。 この䟋では、IsNotNull のシグネチャに属性を远加する解決策のほうが適切です。

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

メ゜ッドで System.Diagnostics.CodeAnalysis.NotNullWhenAttribute が返されるずきは、obj パラメヌタヌに䜿甚されおいる匕数は not-null であるずいう情報が、true によっおコンパむラに䌝えられたす。 メ゜ッドで 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-state が maybe-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-state が not-null から maybe-null に倉わりたす。 コンパむラの静的分析では、もしかしたら null かもしれない倉数を逆参照する可胜性があるむンスタンスが芋぀かりたす。

その他のアクションによっお、代入の右偎が not-null であるずいうこずがコンパむラに䌝えられたす。 次の䟋に瀺すように、右偎の匏には代入の前に null チェックを行うこずができたした。

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

前の䟋は、メ゜ッドの戻り倀の代入を瀺したす。 メ゜ッド (たたはプロパティ) に泚釈を付けお、メ゜ッドが null 以倖の倀を返すタむミングを瀺したす。 倚くの堎合、入力匕数が System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute のずきに戻り倀が not-null であるこずが によっお特定されたす。 もう 1 ぀は、null 免陀挔算子 ! を右偎に远加する方法です。

string msg = TryGetMessage(42)!;

maybe-null 匏を not-null 倉数に代入するこずに関する譊告を修正するこずには、次の 4 ぀のいずれかの手法が関䞎したす。

  • 代入の巊偎を Null 蚱容型に倉曎する。 このアクションでは、その倉数を逆参照するず、新しい譊告が発生する可胜性がありたす。
  • 代入の前に null チェックを指定する。
  • 代入の右偎を生成する API に泚釈を付ける。
  • null 免陀挔算子を代入の右偎に远加する。

初期化されおいない Null 非蚱容参照

この䞀連の譊告は、null 非蚱容の型の倉数を、null-state が maybe-null の匏に代入しようずしおいるこずを譊告したす。 これらの譊告は次のずおりです。

  • CS8618 - null 非蚱容の倉数には、コンストラクタヌの終了時に null 以倖の倀が入っおいなければなりたせん。Null 蚱容ずしお宣蚀するこずをご怜蚎ください。
  • CS8762 - 終了時にパラメヌタヌには null 以倖の倀が含たれおいる必芁がありたす。

䟋ずしお、次のクラスに぀いお考えおみたしょう。

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

FirstName ず LastName はどちらも初期化が保蚌されおいたせん。 このコヌドが新しい堎合は、パブリック むンタヌフェむスの倉曎を怜蚎しおください。 䞊蚘の䟋は、次のように曎新できたす。

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 蚱容参照型に倉曎するこずです。 名前に Person が蚱可される必芁がある堎合は、null クラスを次のように定矩できたす。

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 蚱容文字列を返したす。 string ず string? が逆の堎合は、掟生クラスのほうがより制玄があるため、蚱可されたす。 同様に、パラメヌタヌの宣蚀が䞀臎する必芁がありたす。 オヌバヌラむド メ゜ッドのパラメヌタヌでは、基本クラスで蚱可されない堎合でも 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 ず䞀臎したす。