[C#入門]第8回 NULL許容型

はじめに

値型の変数にnull値を格納したい場合があります。このような場合に使用できるのがNULL許容型です。

今回は、このNULL許容型について説明します。

目次

NULL許容型の宣言

int型は、整数を格納できる変数ですので、必ず何かしらの数値が入っています。しかし、場合によっては int型の変数に「何もない」という状態を代入したい場合があります。

例えば、ある数値を割り算して結果を int型の変数に代入するとしましょう。しかし、ゼロで割り算をした場合は、エラーが発生してしまい、その変数に計算結果が代入されることはありません。この場合は、変数の宣言時に代入した初期値がそのまま残ることとなります(初期値が0の場合は、変数の値は0のままです)。計算によって得られた値が代入されたのか、初期値が代入されたままなのかを判断することはできません。

このような場合、「何もない」ということを表す null を初期値として代入することができれば、正しく計算された場合はその値が、計算に失敗した場合はnullが残ります。

通常の int型 は null を代入することはできませんので、nullを代入可能な「NULL許容型」というものを使用します。NULL許容型は、値型に?を付けた形で宣言をします。

int型での例を以下に示します。

C#でのNULL許容型の例
int dataX = 0;      // 通常のint型
int? dataY = null;  // NULL許容型
VB.NETでのNULL許容型の例

VB.NETもNULL許容型があります。ただしVB.NETはNULLではなくNothingであるという点で異なります。

Dim dataX As Integer = 0 '通常のint型
Dim dataY As Integer? = Nothing 'NULL許容型(Nothingを代入できる)
JavaでのNULL許容型の例

JavaにはNULL許容型はありません。代わりに値型に対するラッパークラスを使用することで null を扱うことができます。

int dataX = 0;	// 通常のint型
Integer dataY = null;	// int型のラッパークラス
SwiftにおけるNULL許容型の例

SwiftにもNULL許容型があります。ただしSwiftではnullではなく「nil」という値を使用します。nil は nullと同義です。

var dataX : Int = 0
var dataY : Int? = nil

Nullable<T>構造体

※本連載ではまだ構造体について説明していないので、読み飛ばしても構いません。

NULL許容型は、実際はNullable<T>構造体と等価です。

例えば、以下の2つの変数は同じデータ型です。

C#におけるNULL許容型とNullable<T>構造体の例
int? x;
Nullable<int> y;

Nullable<T>構造体は、以下のプロパティを持っています。

プロパティ 説明
HasValue nullではない有効な値を持っている場合はtrue
Value 有効な値を返す。但し、HasValueプロパティがfalseの場合は例外が発生します。

NULL許容型の型変換

値型TからNULL許容型のT?に対しては、暗黙的な型変換が可能です。値型Tは、必ずNULL以外の値が入っていることが保証されているためです。

以下に例を示します。

C#におけるT→T?への型変換例
int x = 5;
int? y = null;

// T→T?は暗黙的な型変換が可能
y = x;

int z = 0;

// T?→Tは明示的なキャストが必要
z = (int)y;

// (int)y は y.Value と等価
//z = y.Value;

VB.NETはC#と同様で、T→T?へは暗黙的な型変換が可能です。

VB.NETにおけるT→T?への型変換例
Dim x As Integer = 5
Dim y As Integer? = Nothing

' T→T?は暗黙的な型変換が可能
y = x

Dim z As Integer = 0

' T?→Tは明示的なキャストが必要
z = CInt(y)

' CInt(y) は y.Value と等価
'z = y.Value

 

Javaの場合は、値型からラッパークラス、ラッパークラスから値型の両方とも暗黙的にキャストが行われます。

Javaにおける値型→ラッパークラスへの型変換例
int x = 5;
Integer y = null;

// 値型→ラッパークラス は暗黙的な型変換が可能
//y = x;

int z = 0;

// 明示的なキャストをしなくても ラッパークラス→値型 への代入が可能
z = y;

// (int)y は y.intValue() と等価
//z = y.intValue();

 

Swiftの場合も値型からオプショナル型へは暗黙的キャストが行われます。オプショナル型から値型への代入は、強制アンラップ(変数名の後ろに!をつける)して代入可能です。

SwiftにおけるT→T?型への型変換例
var x : Int = 5
var y : Int? = nil

// 値型→オプショナル型へは暗黙的な型変換が可能
y = x

var z : Int = 0

// オプショナル型→値型へは強制アンラップで代入可能
z = y!

NULL合体演算子

C#ではNULL合体演算子「??」があります。「??」演算子を使用すると、nullかどうかを判断して、nullの場合は別の値を割り当てることができます。

以下に例を示します。

C#におけるNULL合体演算子の使用例
int? x = null;
int y = 0;

// x が nullの場合は yに5が代入される
y = x ?? 5;

 

VB.NETとJavaにはNULL合体演算子はありません。

Swiftの場合は、C#と同様に??演算子があります。

SwiftにおけるNULL合体演算子の使用例
var x : Int? = nil
var y : Int = 0

// x が nullの場合は yに5が代入される
y = x ?? 5



コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください