##C#NULL許容値型
ジェネリックSystem.Nullable構造体のインスタンス。
NULL許容値型は、元になる値型の未定義の値を表す必要があるときに使用します。
ブール変数で可能なのは、trueまたfalseのいずれ。
ただし、一部のアプリケーションでは、変数の値が未定義または存在しない場合がある。
例えば、データベースフィールドにtrueまたはfalseが含まれている場合や、値が全く含まれていない
場合がある。その場合にはbool?型を使用。
宣言と代入
値型は、対応するNULL許容値型に暗黙的に変換できるため、基になる値型の場合と同様に、
NULL許容値型の変数に値を割り当てることが出来る。またNULL値を代入とすることも可。
(既定値はNULL)
NULL許容値型のインスタンスの検査
C#7.0以降では、型パターンでIS演算子を使用して、NULLのNULL許容値型のインスタンスを調べ、
基になる方の値を取得することが出来る。
NULL許容値型の変数の値を確認して取得するには、常に次の読み取り専用プロパティを使用できます。
・Nullable.HasValueはNULL許容値型のインスタンスに、基になる型の値が含まれるかどうかを示す。
・HasValueがTrueの場合Nullable.Valueは基になる型の値を取得。
HasValueがfalseの場合、ValueプロパティはInvalidOperationExceptionをスローする。
NULL許容値型から基になる型への変換
NULL許容値型の値をNULL非許容値型の変数に割り当てる場合は、NULLの代わりに割り当てる値を指定する必要がある。
それを行うには、NULL合体演算子??を使用(Nullable.GetValueOrDefault(T)メソッドも同じ木で使用することが出来る。)
例:
C#
int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}"); // output: b is 28
int? c = null;
int d = c ?? -1;
Console.WreteLine($"d is {d}"); // outlput: d is -1
NUllの代わりに基になる値の既定値を使用する場合は、Nullable.GetValueOrDefault()メソッドを使用
次の例では、NULL居誘致型をNULL非許容型に明示的にキャストすることもできる。
例:
C#
int? n = null;
// int ml = n;
int n2 = (int)n;
実行時にNULL許容値型の値がNULLの場合は、明示的なキャストによってInvalidOperationExceptionがスロー。
NULL非許容値型Tは、対応するNULL許容値型T?に暗黙的に変換される。
リフト演算子
定義済みの単項演算子及び2項演算子、または値型Tによってサポートされるオーバーロードされた任意の演算子は、
対応するNULL許容値型T?でもサポートされます。
“リフト演算子”とも呼ばれるこれらの演算子では、一方または両方のオペランドがNULLの場合にNULLが生成。
それ以外は、そのオペランドに含まれる値を使用して結果が算出される。
C#
int? a = 10;
int? b = null;
int? c = 10;
a++; // a is 11
a = a * c; // a is 11-
a = a + b; // a is null
**比較演算子<,>,<=,>=**では、一方または両方のオペランドがNULLの場合、結果はfalseになる。
それ以外はオペランドに含まれる値が比較。
例えば、<=から返される結果がfalseであっても逆の比較(>)から返される結果がTrueとは限らない。
次の例では
10が
・NULL以上ではなく
・NULL未満でもないことを示します。
C#
int? a = 10;
Console.WriteLine($"{a} >= null is {a >= null}");
Console.WriteLine($"{a} < null is {a < null}");
Console.WriteLine($"{a} == null is {a == null}");
// Output:
// 10 >= null is False
// 10 < null is False
// 10 == null is False
int? b = null;
int? c = null;
Console.WriteLine($"null >= null is {b >= c}");
Console.WriteLine($"null == null is {b == c}");
// Output:
// null >= null is False
// null == null is True
**等値演算子 ==**では、両方のオペランドが null の場合、結果は true になります。一方のオペランドだけが null の場合、結果は false です。それ以外の場合は、オペランドに含まれる値が比較されます。
**非等値演算子 !=**では、両方のオペランドが null の場合、結果は false になります。一方のオペランドだけが null の場合、結果は true です。それ以外の場合は、オペランドに含まれる値が比較されます。
2 つの値型の間にユーザー定義の変換が存在する場合は、それに対応する null 許容値型間でも同じ変換を使用することができます。
参考資料:
・Microsoft リファレンス
・C#の絵本