[C#][VB.NET] NULLの扱い(NULL合体演算子とNULL条件演算子)

[C#][VB.NET] NULLの扱い(NULL合体演算子とNULL条件演算子)

NULL(Nothing)の扱いについて

C#/VB.NETにおいて、オブジェクトの中身がNULL(Nothing)の場合、そのオブジェクトを参照すると、NullReferenceExceptionの例外が発生してしまいます。つまり参照前にNULL判定をしてやる必要があります。

C#/VB.NETには、NULLの扱いについて、便利な演算子・構文がいろいろと追加されています。

NULL条件演算子(?.)、NULL合体演算子(??)、三項演算子(?)など検索しにくい演算子ですが使いこなせればかなり便利です。
それぞれC#, VB.NETでのサンプルコードを用意しました。

VB.NETにはNULL合体演算子(??)が存在しません。

if文での判定

まず一番単純な判定方法が、if文を使うものです。NULLでない場合のみ参照を行う方法です。コードが長くなりますが誰が見てもすぐに分かるものです。

C#

// NULL
object val = null;
// if文でNULL判定
if (val == null)
{
    Console.WriteLine("NULLです ...");
}

VB.NET

Dim val As Object = Nothing
If val Is Nothing Then
    Console.WriteLine("Nothingです ...")
End If

三項演算子を使う

if文での判定は複数行にわたるので、コードが長くなり可読性が劣ります。そこで三項演算子を使うことで1行のコードで判定を行えます。が、ややわかりにくいのが難点でしょうか。

三項演算子では、左の条件式がTrueの場合に、中央の式が評価され、Falseの場合は右の式が評価されます。

C#

string val1 = null;
string val2 = "あいうえお";
// 三項演算子を使って判定
Console.WriteLine(val1 == null ? "val1 は NULLです ..." : val1);
Console.WriteLine(val2 == null ? "val2 は NULLです ..." : val2);

VB.NET

Dim val1 As String = Nothing
Dim val2 As String = Nothing
Console.WriteLine(If(val1 Is Nothing, "val1 は Nothingです ...", val1))
Console.WriteLine(If(val2 Is Nothing, "val2 は Nothingです ...", val2))

NULLと空文字の判定を行う(IsNullOrEmpty)

String.IsNullOrEmpty メソッドを使用することで、指定された文字列が Null または Empty 文字列であるかどうかを判定できます。空文字の判定にはこれを使うほうがスマートです。さらにスペースの場合の判定も追加するには、IsNullOrWhiteSpace メソッド を使用できます。

C#

string val1 = null;
string val2 = "";
if (string.IsNullOrEmpty(val1))
{
    Console.WriteLine("val1 NULLもしくは空文字です ...");
}
if (string.IsNullOrEmpty(val2))
{
    Console.WriteLine("val2 NULLもしくは空文字です ...");
}

VB.NET

Dim val1 As String = Nothing
Dim val2 As String = ""
If String.IsNullOrEmpty(val1) Then
    Console.WriteLine("val1   Nothingもしくは空文字です ...")
End If
If String.IsNullOrEmpty(val2) Then
    Console.WriteLine("val2 Nothingもしくは空文字です ...")
End If

NULL合体演算子(??)を使う

NULL合体演算子(??)と呼ばれる演算子を使えば三項演算子より簡潔に判定を行えます。
??演算子の左辺がNULLの場合、右辺の式で評価され、NULL以外の場合は左辺の値がそのまま使用されます。

VB.NETにはNULL合体演算子(??)が存在しません。

C#

// NULL合体演算子(??)
string val1 = null;
Console.WriteLine(val1 ?? "NULLです ...");

// NULL許容型のintを計算
int? val2 = null;
var result = 1 + val2 ?? 2; // 1 + 2
Console.WriteLine(result);

NULL条件演算子(?.)を使う

stringやNULL許容型の値をそのまま使用する場合はNULL合体演算子や三項演算子を使えばいいのですが、オブジェクト自体がNULLかどうか判定した後にプロパティにアクセスするという処理を書く場合はNULL条件演算子(?.)を使えます。

NULL条件演算子(?.)を使ってオブジェクトのメンバにアクセスすれば、NULLの場合はNULLを返し、そうでない場合はメンバの値を返します。
このNULL条件演算子と(?.)とNULL合体演算子(??)を組み合わせてNULLの場合の処理を簡潔に書くことができます。

C#

int[] numbers = null;
// NULL条件演算子(?.)でメンバ、インデックス操作
// NULL合体演算子(??)でNULLの値を0として扱う
Console.WriteLine(numbers?.Length ?? 0);    // 0
Console.WriteLine(numbers?[0] ?? 0);        // 0

VB.NET

Dim numbers As Integer() = Nothing
' NULL条件演算子(?.)でメンバ、インデックス操作
Console.WriteLine(numbers?.Length)  ' nothingなので空
Console.WriteLine(numbers?(0))      ' nothingなので空

NULL許容型を使う

値型は通常NULL値をとることができませんが、データベースをの値などではNULLを取る数値なども考えられます。一例として、ASP.NET MVCではNULL許容のフィールドを定義する際、モデルのプロパティでNULL許容型を使います。

使い方は単純で通常の値型変数の宣言で、型名の後ろに ? をつけてやるだけです。これでNULLもしくは元の型の値を取る新しい方を作れます。

元の型 T から NULL許容型 T? への変換は暗黙的に行なえますが、その逆はNULLの場合があるのでうまく行きません。

T? には 複数のプロパティがあり、値を取り出す際に使用します。が、実際には上ですでに使ったようにNULL合算演算子(??)を使ったほうがすっきりします。

名前 説明
HasValue 現在の Nullable オブジェクトに、基になる型の有効値があるかどうかを示す値を取得します。中身がNULLかどうかの判定をします。
Value 有効な値を返します。NULLの場合には例外(InvalidOperationException)が発生します。

C#

int? val1 = null;
int? val2 = 1;
if (val1.HasValue)
{
    Console.WriteLine(val1.Value);
}
if (val2.HasValue)
{
    Console.WriteLine(val2.Value);
}

VB.NET

Dim val1 As Integer? = Nothing
Dim val2 As Integer? = 1
If val1.HasValue Then
    Console.WriteLine(val1.Value)
End If
If val2.HasValue Then
    Console.WriteLine(val2.Value)
End If

まとめ

NULL合算演算子(??)とNULL条件演算子(?.)を使うことで長くなりがちなコードを簡潔に1行で書くことができます。
ただし、VB.NETではNULL合算演算子(??)がないのでIIFもしくはif文での判定を使用する必要があります。

参考URL

C#カテゴリの最新記事