Share via


Null 許容型の使用 (C# プログラミング ガイド)

Null 許容型は、基底の型のすべての値に加えて、null 値を表すことができます。 Null 許容型は、次のいずれかの形式で宣言します。

System.Nullable<T> variable

または

T? variable

T は、Null 許容型の基底の型です。 T には、struct を含む任意の値型を指定できますが、参照型は指定できません。

Null 許容型を使用するときの例として、通常のブール型変数が、true と false の 2 つの値をどのように持つことができるかを考えてみましょう。 この変数には、"未定義" を示す値はありません。 多くのプログラミング アプリケーションの中でも特にデータベース操作では、変数が未定義の状態で現れることがあります。 たとえば、データベース フィールドには、true や false の値が入力されている場合がありますが、値が入力されていない場合もあります。 また、参照型に null を設定すると、その型が初期化されていないことを示すことができます。

このような違いから、ステータス情報を格納する変数を追加したり、特別な値を使用したりするような余分なプログラミング作業が生じることがあります。 C# では、Null 許容型修飾子により、未定義の値を示す値型変数を作成できます。

Null 許容型の例

Null 許容型の基底の型には、任意の値型を使用できます。 次に例を示します。

int? i = 10;
double? d1 = 3.14;
bool? flag = null;
char? letter = 'a';
int?[] arr = new int?[10];

Null 許容型のメンバー

Null 許容型の各インスタンスには、次のような読み取り専用の 2 つのパブリック プロパティがあります。

  • HasValue

    HasValue は bool 型です。 変数が null 以外の値を格納している場合、このプロパティには true が設定されます。

  • Value

    Value は、基底の型と同じ型です。 HasValue が true の場合、Value は、有意な値を格納しています。 HasValue が false の場合、Value にアクセスすると、InvalidOperationException がスローされます。

次の例では、HasValue メンバーを使用して、値を表示する前に、変数に値が格納されているかどうかをテストします。

int? x = 10;
if (x.HasValue)
{
    System.Console.WriteLine(x.Value);
}
else
{
    System.Console.WriteLine("Undefined");
}

値のテストは、次の例のように行うこともできます。

int? y = 10;
if (y != null)
{
    System.Console.WriteLine(y.Value);
}
else
{
    System.Console.WriteLine("Undefined");
}

明示的な変換

Null 許容型は、キャストを明示的に使用するか、または Value プロパティを使用して通常の型にキャストできます。 次に例を示します。

int? n = null;

//int m1 = n;      // Will not compile.
int m2 = (int)n;   // Compiles, but will create an exception if n is null.
int m3 = n.Value;  // Compiles, but will create an exception if n is null.

2 つのデータ型の間でユーザー定義変換を定義している場合は、これらのデータ型の Null 許容バージョンを使用して、同じユーザー定義変換を実行することもできます。

暗黙の型変換

Null 許容型の変数には、次の例のように null キーワードを使用して null に設定できます。

int? n1 = null;

通常の型から Null 許容型への変換は暗黙的です。

int? n2;
n2 = 10;  // Implicit conversion.

演算子

定義済みの単項演算子と二項演算子およびユーザー定義演算子は、いずれも値型を対象にしていますが、Null 許容型でも使用できます。 これらの演算子は、オペランドが null の場合は null 値を生成し、null 以外の場合は、包含されている値に基づいて結果を算出します。 次に例を示します。

int? a = 10;
int? b = null;

a++;         // Increment by 1, now a is 11.
a = a * 10;  // Multiply by 10, now a is 110.
a = a + b;   // Add b, now a is null.

2 つの null 許容型を比較したときに、一方の null 許容型の値が null でもう一方がそれ以外の場合は、!= (等しくない) を除くすべての比較が false と評価されます。 ある比較から返される結果が false であっても、逆のケースから返される結果が true とは限りません。 次の例では、10 は null より大きくも小さくも等しくもありません。 num1 != num2 のみが true です。

int? num1 = 10;
int? num2 = null;
if (num1 >= num2)
{
    Console.WriteLine("num1 is greater than or equal to num2");
}
else
{
    // This clause is selected, but num1 is not less than num2.
    Console.WriteLine("num1 >= num2 returned false (but num1 < num2 also is false)");
}

if (num1 < num2)
{
    Console.WriteLine("num1 is less than num2");
}
else
{
    // The else clause is selected again, but num1 is not greater than
    // or equal to num2.
    Console.WriteLine("num1 < num2 returned false (but num1 >= num2 also is false)");
}

if (num1 != num2)
{
    // This comparison is true, num1 and num2 are not equal.
    Console.WriteLine("Finally, num1 != num2 returns true!");
}

// Change the value of num1, so that both num1 and num2 are null.
num1 = null;
if (num1 == num2)
{
    // The equality comparison returns true when both operands are null.
    Console.WriteLine("num1 == num2 returns true when the value of each is null");
}

/* Output:
 * num1 >= num2 returned false (but num1 < num2 also is false)
 * num1 < num2 returned false (but num1 >= num2 also is false)
 * Finally, num1 != num2 returns true!
 * num1 == num2 returns true when the value of each is null
 */

どちらも null である 2 つの null 許容型を等価比較すると、結果は true になります。

?? 演算子

?? 演算子は、Null 許容型が Null 許容型以外の型に割り当てられているときに返す既定値を定義します。

int? c = null;

// d = c, unless c is null, in which case d = -1.
int d = c ?? -1;

この演算子は、複数の Null 許容型で使用することもできます。 次に例を示します。

int? e = null;
int? f = null;

// g = e or f, unless e and f are both null, in which case g = -1.
int g = e ?? f ?? -1;

bool?type

Null 許容 bool? 型は、truefalsenull の 3 つの異なる値を格納できます。 bool? から bool にキャストする方法については、 「方法: bool? から bool に安全にキャストする (C# プログラミング ガイド)」を参照してください。

Null 許容ブール型は、SQL で使用するブール変数型と同じです。 & 演算子によって生成される結果が SQL の 3 値のブール型と一致するようにするには、 | 次の定義済みの演算子を指定します。

bool? operator &(bool? x, bool? y)

bool? operator |(bool? x, bool? y)

これらの演算子の結果を以下の表に示します。

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

参照

参照

null 許容型 (C# プログラミング ガイド)

Null 許容型のボックス化 (C# プログラミング ガイド)

概念

C# プログラミング ガイド