通常、値型は null 値(無効な値)を取れません。 ところが、データベース等、一部のアプリケーションでは、 値型の通常の(有効な)値と null(無効な値)を取るような型が欲しいときがあります。 そこで、C# 2.0 では、Nullable 型という特殊な型が用意されました。
Nullable 型は、値型の型名の後ろに ? を付ける事で、元の型の値または null の値を取れる型になるというものです。
int 型で例に取ると、以下のような書き方が出来ます。
int? x = 123; int? y = null;
Nullable 型にできるのは値型のみです。
したがって、string? というのは定義できません。
また、Nullable 型自体、参照型になりますので、
int?? (Nullable 型の Nullable 型)と言うのもエラーになります。
T? という書き方で得られる Nullable 型は、
実は、System.Nullable<T> と等価になります。
そして、この型は、
HasValue という bool 型のプロパティと、
Value という T 型のプロパティを持っています。
表1: Nullable<T> 型のメンバー
| 戻り値の型 | プロパティ名 | 説明 |
|---|---|---|
| bool | HasValue | 有効な(null でない)値を持っていれば true、 値が null ならば false を返します。 |
| T | Value | 有効な値を返します。 もし、HasValue が false(値が null)だった場合、 例外 InvalidOperationException をスローします。 |
また、int? x = 123; という書き方ができることから容易に想像が付くように、
T?型 と T 型の間には暗黙の型変換が存在します。
T → T? の変換は常に可能で、
以下のようなコードの下2行は等価になります。
int? x; x = 123; x = new int?(123); // x = 123; と等価。
その逆、
T? → T の変換は、HasValue が true のときのみ可能で、
HasValue が false の時には InvalidOperationException がスローされます。
int? x = 123; int? y = null; int z; z = x; // OK。 z = y; // 例外が発生。
元となる型 T が持っている演算子は、
そのまま Nullable 型 T? に対して利用できます。
表2: Nullable<T> 型に対する演算
| 単項演算 |
+ ++ - -- ! ~
|
オペランドも計算結果も共に T 型の単項演算子がある場合、
T? に対してもその演算子を利用できます。
T? 型のオペランドが null の場合、計算結果も null になります。
|
| 二項演算 |
+ - * / % & | ^
|
(左右両方の)オペランドも計算結果も共に T 型の二項演算子がある場合、
T? に対してもその演算子を利用できます。
T? 型のオペランドのどちらか片方でも null だった場合、計算結果も null になります。
(ただし、bool 型に対する & および | は例外で、
これらに関しては後述します。)
|
| シフト演算 |
<< >>
|
これらも二項演算と同様で、T 型の演算子がある場合、
T? に対してもその演算子を利用できます。
ただし、シフト演算ですので、右オペランドは int 型です。
T? 型の左オペランドが null だった場合、計算結果も null になります。
|
| 等値演算 |
== !=
|
T 型の等値演算がある場合、T? 型の等値判定も可能です。
T? 型の
オペランドが左右とも null の場合、比較結果は等しいと判定されます。
また、有効な(non-null の)値と null は等しくありません。
左右ともに有効な値の場合、T 型の比較結果と同じになります。
|
| 関係演算 |
< > <= >=
|
T 型の比較演算がある場合、T? 型の比較も可能です。
T? 型のオペランドのどちらか片方でも null だった場合、計算結果は false になります。
左右ともに有効な値の場合、T 型の比較結果と同じになります。
|
bool? 型に対する & および | は以下のような結果になります。
表3: bool? に対する &、|
| x | y | x & y | x | y |
|---|---|---|---|
| true | true | true | true |
| true | false | false | true |
| true | null | null | true |
| false | true | false | true |
| false | false | false | false |
| false | null | false | null |
| null | true | null | true |
| null | false | false | null |
| null | null | null | null |
Nullable 型には、?? 演算という特殊な演算があります。 (null coalescing operator といいます。 訳すなら、null 結合演算子。)
?? 演算子は、値が null かどうかを判別し、null の場合には別の値を割り当てる演算子です。
// x, y は int? 型の変数 int? z = x ?? y; // x != null ? x : y int i = z ?? -1; // z != null ? z.Value : -1