どうやったらnullチェックができるの?
null参照を回避したい!
多くのプログラミング言語で使われているnullチェックですが、C#でも必要になるケースは多くありますよね。
こんにちは、現役エンジニア5年目の遠藤です!
今回の記事では、nullチェックの方法やnull参照を回避する方法について解説致します!
この記事はこんな方へ向けて書きました
- nullとは何か知りたい方
- null許容型について知りたい方
- nullの判定方法が知りたい方
本記事を読んでいただければ、nullについての基礎的な知識が一通り理解できます。
ぜひ最後までお付き合いください!
nullとは?
そもそもnullとは、値が無効である事を指します。この場合、そのまま実行しようとしても適切な処理が行えなくなります。
例として、以下のようにオブジェクトがnullとなってしまうケースがあったとします。
var test = Sample(id);
int value = test.Value;
上記のコードでもしSample()が有効なオブジェクトを返せなかった(nullだった)場合、test.Valueを参照した所でSystem.NullReferenceExceptionという例外が発生し、そこで処理が終了してしまいます。
プログラミングをしているとこういったケースがしばしばあります。以降では、nullを判定する方法などについて解説致します。
nullの判定方法
数値型の判定
まずはNullableという、nullを許容できるような型を作る方法について解説致します。これはnull許容型と言い、以下2つのプロパティを持つ事でnull判定等が簡単にできるようになります。
プロパティ名 | 処理内容 |
---|---|
HasValue | 有効な値を持っているかどうかを判定する。値がある場合にtrue, 無効(null)な場合にfalseを返す |
Value | 有効な値を返す。値が無効(null)な場合、InvalidOperationExceptionをスローする。 |
言葉ではわかりにくいので、実際のコードを見てみましょう。Nullableは数値に対して可能であるため、今回は例としてintのnull許容型を使います。
using System;
namespace Null_Check
{
class Nullable
{
static void Main()
{
Nullable num1 = 256; //null許容型の宣言
Nullable num2 = null; //null許容型に無効値(null)を代入
//有効値が代入されているnum1の確認
Console.WriteLine(num1.HasValue);
Console.WriteLine(num1.Value); //有効値の取得
//nullとなっているnum2の確認
Console.WriteLine(num2.HasValue); //nullかどうかの判定
try
{
var value = num2.Value; //num2の有効値を取得(num2は無効値なのでExceptionが発生する)
}
catch(InvalidOperationException e)
{
Console.WriteLine("!!!Exception!!!");
Console.WriteLine(e);
}
}
}
}
実行結果:
True
256
False
...
!!!Exception!!!
...
System.InvalidOperationException: Nullable object must have a value.
at System.Nullable`1.get_Value()
at Null_Check.Nullable.Main() in c:pathSample.cs:line 20
Nullableを使う事によって、上記のようにnullを判定しながら処理を進める事が可能になります。
また、Nullableを使わずとも「?」を使う事でnull許容型の宣言ができます。以下のように記述する事で、Nullableと同じ宣言をした事になります。
int? num = null;
先ほどのサンプルコードの宣言時の書き方を上記のように変更しても、同じように動作させる事ができます。
文字列型の判定
先ほどは数値におけるnull判定のケースでしたが、文字列型でnullや空文字を判定する方法もあります。
文字列を判定する場合、以下のような確認方法があります。
using System;
namespace Null_Check
{
class NullString
{
static void Main()
{
string str = null; //nullの場合
Console.WriteLine("nullの場合");
nullCheck(str);
str = ""; //空文字の場合
Console.WriteLine("空の場合");
nullCheck(str);
str = " "; //空白の場合
Console.WriteLine("空白の場合");
nullCheck(str);
str = String.Empty; //Empty状態の場合
Console.WriteLine("Emptyの場合");
nullCheck(str);
}
static void nullCheck(string str)
{
Console.WriteLine(str == null); //文字列 == nullで確認
Console.WriteLine(String.IsNullOrEmpty(str)); // IsNullOrEmpty()で確認
Console.WriteLine(String.IsNullOrWhiteSpace(str)); // IsNullOrWhiteSpace()で確認
}
}
}
実行結果:
nullの場合
True
True
True
空の場合
False
True
True
空白の場合
False
False
True
Emptyの場合
False
True
True
文字列型においてnull, empty, 空, 空白はそれぞれ別物になるので、注意しましょう。
nullを回避する方法
本章では、値がnullの時にどのように回避すれば良いかを解説致します。
if文を使う
回避策としてまず思い浮かぶ方法はif文かと思います。
サンプルコード:
using System;
namespace Null_Check
{
class NullCheck_If
{
static void Main()
{
string sample = null; // nullのstring
if(sample != null)
{
Console.WriteLine(sample.Length);
}
else
{
Console.WriteLine("無効な値です");
}
}
}
}
実行結果:
無効な値です
このようにif(var == null)とする事で判定は可能です。慣れ親しんでいるので実装は簡単かも知れませんね。
ただ、null判定に関してはif文だと行数が多くなってしまうので、この後に紹介する2つの方法がオススメとなります。
条件演算子を使う
冒頭の「nullとは?」では、オブジェクトがnullの時にメンバにアクセスしようとした場合、Null参照の例外が発生することを説明致しました。
このような場合、メンバ等へアクセスする前にそのオブジェクトがnullかどうか判定し、有効な場合にのみアクセスするという方法があります。これによりNull参照の例外を回避する事が可能です。
この場合も「?」を使います。使い方は以下のようになります。
using System;
namespace Null_Check
{
class NullObj
{
static void Main()
{
string sample = null; //nullのString
//Console.WriteLine(sample.Length); //このように書くとNull参照となる
Console.WriteLine(sample?.Length); // sample「?」.Lengthとする事で、null判定を先に行っている
}
}
}
上記のサンプルコードはアクセス前に判定をし、もしnullの時はアクセスしないという処理となります。そのため、上記コードを実行すると何も出力されませんが、Null参照の例外も発生せずに処理が終了します。
このような場合の「?」演算子を条件演算子と言います。また、三項条件演算子という「条件式 ? Trueの時の値 : Falseの時の値」とする使い方も可能です。
サンプルコード:
using System;
namespace Null_Check
{
class NullObj
{
static void Main()
{
string sample = null; //nullのString
Console.WriteLine((sample == null) ? sample.Length : 0); // 条件式:sample == null, Trueの時:sample.Lengthを返す, Falseの時:0を返す
}
}
}
実行結果:
0
合体演算子を使う
代入する値がnullになる事を回避する為に合体演算子というものが使えます。こちらは「??」と記述します。
書き方は「変数 = 代入する値 ?? 代入する値がnullの時に代入する値」です。
サンプルコード:
using System;
namespace Null_Check
{
class NullObj
{
static void Main()
{
string str = null;
string sample = str ?? ""; //nullであるstrを代入せず、文字列の"null"が代入される
Console.WriteLine(sample.Length);
}
}
}
実行結果:
0
空文字を代入したので、実行結果は0となります。
まとめ
今回の記事では、以下の点について解説致しました。
- nullとは?
- nullの判定方法
- nullを回避する方法
null判定はプログラミングをしていくうえでほぼ必ず直面する内容です。
ここで使い方の基礎を覚えて、Null参照で困らないようにしてくださいね!