前回は「例外処理(エラーで止まらないようにする)」をやりました。

今回は、C#で最も多いエラーの元といっても過言ではない、null(ヌル)の話です。これを理解すると、つまずきがぐっと減ります。

null とは、「何も入っていない」という状態のことです。

「空っぽ」を表す、特別な値

これまで、変数には何かしらの値が入っていました。

int age = 20;
string name = "山田";

でも、「まだ何も決まっていない」「該当するものが無い」という状態を表したいこともあります。それが null です。

string name = null;   // 名前が、まだ無い

null は「0」でも「空文字」でもありません。そもそも、何も入っていないという状態です。箱はあるけど、中身が空っぽ。そんなイメージです。

null が、エラーを引き起こす

問題は、中身が無いものを使おうとするときに起きます。

string name = null;
Console.WriteLine(name.Length);   // 名前の文字数を知りたい

name.Length で文字数を取ろうとしていますが、name は null(空っぽ)です。中身が無いのに、その文字数を数えようとして、エラーになります

このエラーには名前があります。NullReferenceException(ヌル参照例外)。C#プログラマーが、いちばんよく見るエラーです。

例えるなら、空っぽの箱を開けて、中身の重さを量ろうとするようなもの。中身が無いのだから、量れるはずがありません。

なぜ、よく起きるのか

null が厄介なのは、思わぬところで紛れ込むからです。

  • メソッドが、結果を見つけられなくて null を返した
  • データベースから取ってきたら、該当データが無くて null だった
  • オブジェクトを作り忘れて、null のままだった(第21回の「new 忘れ」)

「あるはずだ」と思って使ったら、実は null だった。これが、NullReferenceException の典型パターンです。

使う前に、確認する

いちばん基本の対策は、使う前に「null じゃないか」を確認することです。第6回のif文を使います。

string name = GetName();   // 何か名前を取ってくる(null かもしれない)

if (name != null)
{
    Console.WriteLine(name.Length);   // null でないときだけ、使う
}
else
{
    Console.WriteLine("名前がありません");
}

name != null(name は null ではない)を確認してから使う。これで、空っぽの箱を開けてしまう事故を防げます。

null かもしれない、と明示する ── null許容型

ところで、整数(int)のような型は、もともと null を入れられません。

int age = null;   // エラー!int には null を入れられない

でも、「年齢が、まだ未入力(無い)」を表したいこともあります。そんなときは、型のうしろに ? をつけます。これをnull許容型と呼びます。

int? age = null;   // ? をつけると、null を入れられる

int? は「整数、または null」という意味。「この変数は、null になることがありますよ」と、はっきり示せます。

? がついていたら「null かもしれないから、使う前に確認しよう」と気づける。これは、自分にも、コードを読む他の人にも、親切な印になります。

短く確認する書き方

null の確認は、よく使うので、短く書く方法も用意されています。覚えておくと便利です。

// name が null なら "名無し" を使う
string displayName = name ?? "名無し";

// person が null でなければ Name を取る(null なら null のまま)
string? n = person?.Name;
  • ?? … 「左が null なら、右を使う」
  • ?. … 「null でなければ、その先にアクセスする」

最初は if (name != null) で十分です。慣れてきたら、こういう短い書き方も使えると、コードがすっきりします。

つまずきポイント

初心者がはまるのは、やはり NullReferenceException です。このエラーが出たら、原因はほぼ1つ。

「中身が無い(null の)ものを、使おうとしている」

エラーが出たら、「このとき、本当に中身が入っていたかな?」と疑ってみてください。

  • new し忘れていないか(第21回)
  • メソッドが null を返していないか
  • データが見つからず null になっていないか

null は、慣れるまでは手強い相手です。でも「使う前に確認する」を習慣にすれば、ほとんどの事故は防げます。

まとめ

null は「何も入っていない」という状態。C#で最も多いエラーの元。

if (name != null)              // 使う前に確認
{
    Console.WriteLine(name.Length);
}

int? age = null;               // null許容型(null を入れられる)
string x = name ?? "名無し";    // null なら別の値を使う
  • null は、中身が空っぽの状態
  • null を使おうとすると NullReferenceException
  • 使う前に「null じゃないか」を確認する
  • ? をつけると「null になりうる」と示せる

次回は、C#最大の魅力ともいわれる LINQ です。これまでやってきた List や配列が、劇的に便利になります。