佐々木屋

技術的なことから趣味まで色々書きます

null許容型(null判定)

null許容型を利用する上で重要なnull判定方法をいくつか説明します。

int? a = null;
Dim a As Integer? = Nothing

等価(Is)による条件判断

if文による等価評価(Is)を行います。

if (a == null) {
    Console.WriteLine("nullだ");
}
else {
    Console.WriteLine("nullではない");
}
If a Is Nothing Then
    Console.WriteLine("nullだ")
Else
    Console.WriteLine("nullじゃないよ")
End If


Nullable型

null許容型はNullable型でもあるので、HasValueプロパティが利用できます。

if (a.HasValue) {
    Console.WriteLine("nullではない");
}
else {
    Console.WriteLine("nullだ");
}
If a.HasValue Then
    Console.WriteLine("nullじゃないよ")
Else
    Console.WriteLine("nullだ")
End If


三項演算子

if文を一行にまとめた形です。

Dim a As Integer? = Nothing
Console.WriteLine(a == null ? "nullだよ" : "nullじゃないよ");
Console.WriteLine(If(a Is Nothing, "nullだ", "nullじゃないよ"))

短い振る舞いであれば問題ありませんが、長くなると可読性が著しく落ちます。また、通常のif文と異なり、真偽どちらの場合も書かなければならないというのも欠点です。

null条件演算子

メンバー変数のあとに「?」を付けてプロパティを指定することで、nullではない場合のみそのプロパティが実行されます。これにより、意味のない0を返したりすることを防ぐことが可能です。

Console.WriteLine(a?.ToString().Length); //nullの場合は空が返る
Console.WriteLine(a?.ToString().Length) 'nullの場合は空が返る

また、nullだとエラーをスローしてしまうようなプロパティやメソッドも、この演算子を使用することでnull判定をする必要がなくなりますので、コード自体がすっきりします。

int[] a = null;

//これだとaがnullの場合System.NullReferenceExceptionが発生
Console.WriteLine(a.Length);

//null条件演算子の場合はnull以外の場合のみLengthプロパティが実行される
Console.WriteLine(a?.Length);
Dim a As Integer() = Nothing

'これだとaがnullの場合System.NullReferenceExceptionが発生
Console.WriteLine(a.Length)

'null条件演算子の場合はnull以外の場合のみLengthプロパティが実行される
Console.WriteLine(a?.Length)


null合体演算子

三項演算子より簡潔にnull判定が行えるのがnull合体演算子です。C#のみ利用可能です。
null合体演算子の左辺がnullの場合右辺が評価され、nullではない場合はそのまま左辺が評価されます。但し、三項演算子と異なり、右辺の型と左辺の型を合わせる(厳密にオーバーロードされた型)必要があります。

Console.WriteLine(a ?? 111);            
<aがnullの場合>
111

<aが例えば数値5が入っている場合>
5

null合体演算子はnull条件演算子と併せて使うことで、上記の問題を回避することも可能です。但し、書き方によって可読性が悪くなる場合がありますので注意が必要です。

Console.WriteLine(a?.ToString() ?? "nullだ");
<aがnullの場合>
nullだ

<aが例えば数値5が入っている場合>
5