本文へスキップ
BecomeCoder

C#文法コース · 第6章 例外処理とnull安全 · レッスン49

null許容参照型

ブラウザで完結

導入

「値がない」ことを表すのがnullです。しかしnullをうっかり操作するとNullReferenceException——最も多いバグの1つ——が起きます。C#は型で「nullが入りうるか」を明示し、この事故を未然に防ぎます。

図解

flowchart LR
    A["string name<br/>null を入れられない"] -->|安全| U1["name.Length は常にOK"]
    B["string? nickname<br/>null が入りうる(?付き)"] -->|要注意| U2["使う前に null チェック必須"]
    style B fill:#fff3e0

サンプル

string name = "Taro";       // 通常の string は null を想定しない
Console.WriteLine(name.Length);   // 4(安全)

string? nickname = null;    // string? は「null が入りうる」ことを型で表す
// Console.WriteLine(nickname.Length);  // ← コンパイラが「nullかも」と警告する

// null チェックしてから使えば安全
if (nickname != null)
{
    Console.WriteLine(nickname.Length);
}
else
{
    Console.WriteLine("ニックネーム未設定");   // これが出力される
}
  • stringは「nullを入れない」型、string?(?付き)は「nullが入りうる」型
  • string?をチェックなしで使うとコンパイラが警告してくれる
  • 「nullかもしれない値」は使う前にチェックする習慣が身につく

補足: null許容値型(int? など)

intboolのような値型は本来nullを入れられませんが、?を付けたnull許容値型にすると「値なし」を表せます。DBの空欄や「未入力」を扱うときに便利です。

int? count = null;              // 値型でも ? を付ければ null を持てる
Console.WriteLine(count.HasValue);          // False(値が入っているか)

count = 5;
Console.WriteLine(count.HasValue);          // True
Console.WriteLine(count.Value);             // 5(中身。HasValueがtrueのときだけ安全)
Console.WriteLine(count.GetValueOrDefault(0)); // 5(nullなら0を返す)
  • int?bool?など、値型も?で「値なし(null)」を表せる
  • .HasValueで値の有無、.Valueで中身、.GetValueOrDefault(既定値)でnull時の代替値

演習

string? message = null;

// TODO: message が null なら "メッセージなし"、そうでなければ message を出力してください
___
  • 期待される出力: メッセージなし
ヒント1を見る

if (message != null) ... else ... で分岐します

ヒント2を見る

if (message != null) Console.WriteLine(message); else Console.WriteLine("メッセージなし");

まとめ

  • 型?は「nullが入りうる」ことを型で明示する
  • チェックせずに使うとコンパイラが警告する
  • nullチェックの習慣でNullReferenceExceptionを防ぐ

次回: nullを短く安全に扱う演算子?.??です。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。