1. はじめに
なんでNRTは別で有効化しないといけないの?
Nullable Reference Types (NRT)は、ただのシンタックスシュガーじゃなくて、null絡みのバグと戦うコンパイラの強力な味方なんだ。でも歴史的な理由で、古いプロジェクトではデフォルトで有効になってない。互換性を壊さないためだね。もし新しい.NETプロジェクト(たとえば.NET 7、8、9とか)を作るなら、NRTはたぶん最初から有効になってる。でもプロジェクトが古かったり、自分でコントロールしたい場合は、明示的に設定しないとダメ。
Nullable Reference Typesモードって何してくれるの?
このモードが有効だと、コンパイラがどの参照型変数がnullになりうるか、どれがならないかを解析してくれる。実行時には何も変わらないけど、怪しいところがあれば警告をいっぱい出してくれる。信頼できて、わかりやすくて、堅牢なコードを書くのにめっちゃ便利!
NRTモードが有効かどうか確認するには?
新しい.NET 6以上のプロジェクトなら、たぶんNRTはもう有効。でも念のためチェックしよう!
- プロジェクトファイルを開く。たいてい拡張子が.csprojのファイルだよ。
- 最初の<PropertyGroup>タグの中に<Nullable>設定があるか探すか、なければ追加しよう。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
もし<Nullable>disable</Nullable>って書いてあったら、NRTチェックはオフだよ。
2. NRTモードを有効にする方法
.csproj経由で―プロジェクト全体に適用
- .csprojファイルを開く(または作る)。
- <PropertyGroup>ブロックの中に、次の行を追加または編集する:
<Nullable>enable</Nullable>
これでコンパイラはプロジェクト内のすべての.csファイルをしっかりチェックして、nullへの危険なアクセスを警告してくれるよ。
なんでこうするの?
これはグローバルな設定だから。これ以降、プロジェクト全体が新しいルールで動く:nullは常に疑われる存在、油断は許されない!
特定のファイルやコードだけで有効化したい場合
まだ全体を厳しくしたくないなら、まずは一部のファイルで試してみよう。プリプロセッサディレクティブを使うよ:
#nullable enable
string? value = null; // ここは解析オン
#nullable disable
string legacyValue = null; // ここはオフ
#nullable restore
- #nullable enable ― ファイルの最後までチェックを有効化。
- #nullable disable ― チェックを無効化。
- #nullable restore ― .csprojや外部ファイルの設定に戻す。
これ便利! 新しいモジュールだけ厳しくして、古い不安定なコードはそのままにできるよ。
<Nullable>で他に指定できる値
| 値 | 動作 |
|---|---|
|
全部有効:アノテーションも警告も出る |
|
null参照解析を完全にオフ |
|
警告だけ、アノテーションは必須じゃない |
|
アノテーションは必要だけど、コンパイラは怒らない |
|
元の動作に戻す(たとえばグローバル設定から) |
普通はenableかdisableを使うよ。
3. サンプルでデモ
NRT有効化前
// 古いモード、NRTオフ
string s = null; // 文句なし
Console.WriteLine(s.Length); // 危険! NullReferenceExceptionの可能性
NRT有効化後
// 新しいモード、NRTオン
string s = null; // 警告: nullの代入の可能性
Console.WriteLine(s.Length); // 警告: null参照の可能性
これでIDEが怪しい箇所を下線で示してくれるし、コンパイラも警告してくれる:Dereference of a possibly null reference. (CS8602)
どうやって直す?
string? s = null;
if (s != null)
{
Console.WriteLine(s.Length);
}
こうやって「この変数はnullになるかも」って明示すれば、コンパイラも納得してくれる。
4. プロジェクトが「レガシー」な場合は?
昔のプロジェクトは、nullがほぼすべての参照型変数に普通に使われてた時代のもの。NRTを有効にすると、厳しい監査官を雇ったみたいに、怪しいところ全部に警告が出るよ。
警告が多すぎる場合は?
焦らなくてOK―これはエラーじゃなくてヒント。プログラムはちゃんとコンパイルできる。
- 新しいファイルだけNRTを有効にするのもアリ。
- 少しずつコードを整理しよう:?を追加したり、nullチェックしたり、!を使ったり(これは後で説明)。
- nullを丁寧に扱えば、後で困ることが減るよ。
後方互換性と外部ライブラリ
- NRTを有効にしても実行時の挙動は変わらない、コンパイル時の解析だけ。
- 古いコードは一気に警告が増えるかも。
- NRTアノテーションがないライブラリを使ってる場合、コンパイラは慎重になって「全部nullかも」と思ってくれる。
GO TO FULL VERSION