C#のnull許容参照型
C# 8.0から参照型に対してnull許容の可否を指定できるようになりました。Null許容参照型(Nullable Reference Types)は、参照型がnull
になりうるかどうかをコンパイル時に識別し、潜在的なNullReferenceException
を防ぐための機能です。これは、開発者がnull
チェックを怠ったことによるランタイムエラーを減らすことを目的としています。
8.0以前では値型はnull許容の可否が指定できましたが(int? など)、参照型は全てnull許容でした。この機能を有効にした場合、参照型に対して T? と書くとnull許容になり、単に T と書くとnullを認めない型になります。ただし、null非許容を指定した上でnullを代入してもエラーにはならず警告が出るのみです。
null許容参照型の導入により、参照型は以下の2つのカテゴリに分けられます。
- Null非許容参照型(Non-nullable Reference Type): これがデフォルトの動作です。変数は
null
を保持しないことが意図されており、コンパイラはnull
が代入される可能性や、初期化されていない状態で使用される可能性を警告します。 - Null許容参照型(Nullable Reference Type): 変数が
null
を保持する可能性があることを明示的に示します。型名の後ろに?
を付けて宣言します(例:string?
)。コンパイラは、null
になりうる参照型を使用する際に、null
チェックが適切に行われているかを確認します。
null許容コンテクスト
null許容コンテキスト(Nullable Context)とは、Null許容参照型(Nullable Reference Types)機能が有効になっているかどうかを示す、コンパイラの振る舞いを決定する設定のことです。このコンテキストによって、参照型がデフォルトでnull非許容として扱われるか、それともnull関連の警告が発せられるか、などが変わってきます。
null許容の可否を、null許容コンテクスト(nullable context)と呼びます。ソースコードの行単位で指定するか、もしくはプロジェクト全体で指定することができます。
プロジェクト全体のnull許容コンテクスト
プロジェクト全体に対してnull許容を設定することができます。プロジェクトファイル(.prj)で以下のようにnullableオプションを指定します。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<Nullable>enable</Nullable>
...
</PropertyGroup>
</Project>
<Nullable>として指定できるオプションは以下の通りです。
オプション値 | null逆参照警告 | null割当て警告 | null許容の状態 |
disable | × | × | 参照型は全てnull許容です。 C#8.0より前の状態と同じです。 |
enable | ○ | ○ | ? で宣言されている場合を除き参照型はnull 非許容です。 |
warnings | ○ | × | 参照型は全てnull許容です。 |
annotations | × | × | ? で宣言されている場合を除き参照型はnull 非許容です。 |
nullableディレクティブ
ディレクティブを使ってnull許容のコンテキストを変更することができます。
基本的な設定
- #nullable enable: null 許容注釈と null 許容を、有効に設定します。
- #nullable disable: null 許容注釈と null 許容を、無効に設定します。
- #nullable restore: null 許容注釈と null 許容を、プロジェクトの既定に戻します。
public class Sample
{
#nullable disable
public T GetValue()
{
…
}
#nullable enable
}
警告コンテキストの設定
- #nullable disable warnings: null 許容警告を無効に設定します。
- #nullable enable warnings: null 許容警告を有効に設定します。
- #nullable restore warnings:null 許容警告をプロジェクトの既定に戻します。
アノテーションコンテキストの設定
- #nullable disable annotations: null 許容アノテーションを無効に設定します。
- #nullable enable annotations: null 許容アノテーションを有効に設定します。
- #nullable restore annotations: アノテーションの警告コンテキストをプロジェクト設定に復元します。
コンテキストの組み合わせ
null強要に関する警告とアノテーションの設定は組み合わせで以下の9つのケースを作ります。
警告 | null許容 アノテーション | ユースケース |
プロジェクト既定 | プロジェクト既定 | プロジェクト既定に従う。 |
enable | disable | 警告のみ有効にする。 |
enable | project default | 警告を有効にする。 |
project default | enable | アノテーションを有効にする。 |
enable | enable | 既に「null許容参照型」対応に移行されたコードで使用する。 新規プロジェクトと同じ状態。 |
disable | enable | アノテーションを有効にするが警告は出さない。 レガシープロジェクトをこれから修正する場合に使用する。 |
disable | disable | 移行済のコードにレガシーなコードを追加する場合に使用する。 |
project default | disable | 使うケースは滅多にない。 |
disable | project default | 使うケースは滅多にない。 |
レガシーなプロジェクトを使用してコードを追加する場合などには、そのままnull許容を有効にすると大量の警告が出てしまいます。そこで、このようにnull許容のコンテクストを細かく制御することで最適な移行プロセスを選択することができます。
null免除演算子
C#のnull免除演算子 (!
) は、Null許容参照型が有効なコンテキストにおいて、開発者が「この式はnull
ではない」とコンパイラに保証するために使用する単項演算子です。
簡単に言えば、コンパイラがnull
である可能性を検出した場合でも、開発者がその変数が実行時にはnull
ではないと確信している場合に、コンパイラの警告を抑制するために使われます。
#nullable enable
string? name = GetUserName(); // GetUserName()はnullを返す可能性があるとする
Console.WriteLine(name.Length); // 警告: nullの可能性のある参照を逆参照しています
Console.WriteLine(name!.Length); // 警告なし
参照ページ

コメント