導入
「値がない」ことを表すのが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? など)
intやboolのような値型は本来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を短く安全に扱う演算子?.と??です。