null 許容値型 (C# リファレンス)Nullable value types (C# reference)

null 許容値型 T? は、基になる値型 T のすべての値と、追加の null 値を表します。A nullable value type T? represents all values of its underlying value type T and an additional null value. たとえば、bool? 変数には、truefalsenull の 3 つの値のいずれかを割り当てることができます。For example, you can assign any of the following three values to a bool? variable: true, false, or null. 基になる値型 T を null 許容値型にすることはできません。An underlying value type T cannot be a nullable value type itself.

注意

C# 8.0 で、Null 許容参照型機能が導入されました。C# 8.0 introduces the nullable reference types feature. 詳細については、「null 許容参照型」を参照してください。For more information, see Nullable reference types. null 許容値型は、C# 2 から使用できます。The nullable value types are available beginning with C# 2.

null 許容値型は、ジェネリック System.Nullable<T> 構造体のインスタンスです。Any nullable value type is an instance of the generic System.Nullable<T> structure. Nullable<T> または T? の代替可能な形式のいずれかで基になる型 T を持つ null 許容値型を参照できます。You can refer to a nullable value type with an underlying type T in any of the following interchangeable forms: Nullable<T> or T?.

null 許容値型は通常、基になる値型の未定義の値を表す必要があるときに使用します。You typically use a nullable value type when you need to represent the undefined value of an underlying value type. たとえば、ブール型 (bool) 変数で可能なのは、true または false のいずれかです。For example, a Boolean, or bool, variable can only be either true or false. ただし、一部のアプリケーションでは、変数の値が未定義または存在しない場合があります。However, in some applications a variable value can be undefined or missing. たとえば、データベース フィールドに、true または false が含まれている場合や、値がまったく含まれていない場合 (NULL) があります。For example, a database field may contain true or false, or it may contain no value at all, that is, NULL. このシナリオでは、bool? 型を使用できます。You can use the bool? type in that scenario.

宣言と代入Declaration and assignment

値型は、対応する null 許容値型に暗黙的に変換できるため、基になる値型の場合と同様に、null 許容値型の変数に値を割り当てることができます。As a value type is implicitly convertible to the corresponding nullable value type, you can assign a value to a variable of a nullable value type as you would do that for its underlying value type. null 値を代入することもできます。You also can assign the null value. 次に例を示します。For example:

double? pi = 3.14;
char? letter = 'a';

int m2 = 10;
int? m = m2;

bool? flag = null;

// An array of a nullable type:
int?[] arr = new int?[10];

null 許容値型の既定値は null を表します。つまり、Nullable<T>.HasValue プロパティが false を返すインスタンスです。The default value of a nullable value type represents null, that is, it's an instance whose Nullable<T>.HasValue property returns false.

null 許容値型のインスタンスの検査Examination of an instance of a nullable value type

C# 7.0 以降では、型パターンで is 演算子を使用して、null の null 許容値型のインスタンスを調べ、基になる型の値を取得することができます。Beginning with C# 7.0, you can use the is operator with a type pattern to both examine an instance of a nullable value type for null and retrieve a value of an underlying type:

int? a = 42;
if (a is int valueOfA)
{
    Console.WriteLine($"a is {valueOfA}");
}
else
{
    Console.WriteLine("a does not have a value");
}
// Output:
// a is 42

null 許容値型の変数の値を確認して取得するには、常に次の読み取り専用プロパティを使用できます。You always can use the following read-only properties to examine and get a value of a nullable value type variable:

次の例では、HasValue プロパティを使用して、値を表示する前に変数に値が格納されているかどうかをテストします。The following example uses the HasValue property to test whether the variable contains a value before displaying it:

int? b = 10;
if (b.HasValue)
{
    Console.WriteLine($"b is {b.Value}");
}
else
{
    Console.WriteLine("b does not have a value");
}
// Output:
// b is 10

次の例に示すように、HasValue プロパティを使用する代わりに、null 許容値型の変数を null と比較することもできます。You also can compare a variable of a nullable value type with null instead of using the HasValue property, as the following example shows:

int? c = 7;
if (c != null)
{
    Console.WriteLine($"c is {c.Value}");
}
else
{
    Console.WriteLine("c does not have a value");
}
// Output:
// c is 7

null 許容値型から基になる型への変換Conversion from a nullable value type to an underlying type

null 許容値型の値を null 非許容値型の変数に割り当てる場合は、null の代わりに割り当てる値を指定する必要がある場合があります。If you want to assign a value of a nullable value type to a non-nullable value type variable, you might need to specify the value to be assigned in place of null. これを行うには、null 合体演算子 ?? を使用します (Nullable<T>.GetValueOrDefault(T) メソッドも同じ目的で使用することができます)。Use the null-coalescing operator ?? to do that (you also can use the Nullable<T>.GetValueOrDefault(T) method for the same purpose):

int? a = 28;
int b = a ?? -1;
Console.WriteLine($"b is {b}");  // output: b is 28

int? c = null;
int d = c ?? -1;
Console.WriteLine($"d is {d}");  // output: d is -1

null の代わりに基になる値の型の既定値を使用する場合は、Nullable<T>.GetValueOrDefault() メソッドを使用します。If you want to use the default value of the underlying value type in place of null, use the Nullable<T>.GetValueOrDefault() method.

次の例に示すように、null 許容値型を null 非許容型に明示的にキャストすることもできます。You also can explicitly cast a nullable value type to a non-nullable type, as the following example shows:

int? n = null;

//int m1 = n;    // Doesn't compile
int n2 = (int)n; // Compiles, but throws an exception if n is null

実行時に null 許容値型の値が null の場合は、明示的なキャストによって InvalidOperationException がスローされます。At run time, if the value of a nullable value type is null, the explicit cast throws an InvalidOperationException.

null 非許容値型 T は、対応する null 許容値型 T? に暗黙的に変換されます。A non-nullable value type T is implicitly convertible to the corresponding nullable value type T?.

リフト演算子Lifted operators

定義済みの単項演算子および 2 項演算子、または値型 T によってサポートされるオーバーロードされた任意の演算子は、対応する null 許容値型 T? でもサポートされます。The predefined unary and binary operators or any overloaded operators that are supported by a value type T are also supported by the corresponding nullable value type T?. "リフト演算子" とも呼ばれるこれらの演算子では、一方または両方のオペランドが null の場合に null が生成されます。それ以外の場合は、そのオペランドに含まれている値を使用して結果が算出されます。These operators, also known as lifted operators, produce null if one or both operands are null; otherwise, the operator uses the contained values of its operands to calculate the result. 次に例を示します。For example:

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

a++;        // a is 11
a = a * c;  // a is 110
a = a + b;  // a is null

注意

bool? 型の場合、定義済みの & および | 演算子は、このセクションで説明されている規則に従わないことに注意してください。オペランドの 1 つが null の場合も、演算子の評価の結果は null 以外である可能性があります。For the bool? type, the predefined & and | operators don't follow the rules described in this section: the result of an operator evaluation can be non-null even if one of the operands is null. 詳細については、「Boolean logical operators (ブール論理演算子)」記事の「Nullable Boolean logical operators (null 許容論理演算子)」セクションを参照してください。For more information, see the Nullable Boolean logical operators section of the Boolean logical operators article.

比較演算子 <><=>= では、一方または両方のオペランドが null の場合、結果は false になります。それ以外の場合は、オペランドに含まれる値が比較されます。For the comparison operators <, >, <=, and >=, if one or both operands are null, the result is false; otherwise the contained values of operands are compared. ある比較 (たとえば、<=) から返される結果が false であっても、逆の比較 (>) から返される結果が true であるとは限りません。Do not assume that because a particular comparison (for example, <=) returns false, the opposite comparison (>) returns true. 次の例は、10 がThe following example shows that 10 is

  • null 以上ではなくneither greater than or equal to null
  • null 未満でもないことを示しますnor less than null
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 である 2 つの null 許容値型インスタンスの等価比較が true に評価されることも示されています。The preceding example also shows that an equality comparison of two nullable value type instances that are both null evaluates to true.

2 つの値型の間にユーザー定義の変換が存在する場合は、それに対応する null 許容値型間でも同じ変換を使用することができます。If there exists a user-defined conversion between two value types, the same conversion can also be used between the corresponding nullable value types.

ボックス化とボックス化解除Boxing and unboxing

null 許容値型のインスタンス T? は、次のようにボックス化されます。An instance of a nullable value type T? is boxed as follows:

  • HasValuefalse を返した場合は、null 参照が生成されます。If HasValue returns false, the null reference is produced.
  • HasValuetrueを返した場合は、Nullable<T> のインスタンスではなく、基になる値型 T の対応する値がボックス化されます。If HasValue returns true, the corresponding value of the underlying value type T is boxed, not the instance of Nullable<T>.

次の例に示すように、値型 T のボックス化された値を、対応する null 許容値型 T? にボックス化解除できます。You can unbox a boxed value of a value type T to the corresponding nullable value type T?, as the following example shows:

int a = 41;
object aBoxed = a;
int? aNullable = (int?)aBoxed;
Console.WriteLine($"Value of aNullable: {aNullable}");

object aNullableBoxed = aNullable;
if (aNullableBoxed is int valueOfA)
{
    Console.WriteLine($"aNullableBoxed is boxed int: {valueOfA}");
}
// Output:
// Value of aNullable: 41
// aNullableBoxed is boxed int: 41

方法: null 許容値型を識別するHow to identify a nullable value type

次の例は、System.Type インスタンスが構築された null 許容値型 (つまり、指定された型パラメーター T を使用する System.Nullable<T> 型) を表すかどうかを判断する方法を示しています。The following example shows how to determine whether a System.Type instance represents a constructed nullable value type, that is, the System.Nullable<T> type with a specified type parameter T:

Console.WriteLine($"int? is {(IsNullable(typeof(int?)) ? "nullable" : "non nullable")} type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} type");

bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;

// Output:
// int? is nullable type
// int is non-nullable type

例で示されているとおり、System.Type インスタンスの作成には、typeof 演算子を使用します。As the example shows, you use the typeof operator to create a System.Type instance.

インスタンスが null 許容値型かどうかを判断したい場合は、Type インスタンスが前述のコードでテストされるように、Object.GetType メソッドは使用しないでください。If you want to determine whether an instance is of a nullable value type, don't use the Object.GetType method to get a Type instance to be tested with the preceding code. null 許容値型のインスタンスで Object.GetType メソッドを呼び出した場合、そのインスタンスは Objectボクシングされます。When you call the Object.GetType method on an instance of a nullable value type, the instance is boxed to Object. null 許容値型の null 以外のインスタンスのボックス化は、基になる型の値のボックス化と等しいので、GetType は、null 許容値型の基になる型を表す Type インスタンスを返します。As boxing of a non-null instance of a nullable value type is equivalent to boxing of a value of the underlying type, GetType returns a Type instance that represents the underlying type of a nullable value type:

int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32

また、インスタンスが null 許容値型であるかどうかを判断するために、is 演算子を使用しないでください。Also, don't use the is operator to determine whether an instance is of a nullable value type. 次の例に示すように、is 演算子を使用して null 許容値型のインスタンスとその基になる型のインスタンスの型を区別することはできません。As the following example shows, you cannot distinguish types of a nullable value type instance and its underlying type instance with the is operator:

int? a = 14;
if (a is int)
{
    Console.WriteLine("int? instance is compatible with int");
}

int b = 17;
if (b is int?)
{
    Console.WriteLine("int instance is compatible with int?");
}
// Output:
// int? instance is compatible with int
// int instance is compatible with int?

次の例のコードを使用すると、インスタンスが null 許容値型であるかどうかを判別することができます。You can use the code presented in the following example to determine whether an instance is of a nullable value type:

int? a = 14;
Console.WriteLine(IsOfNullableType(a));  // output: True

int b = 17;
Console.WriteLine(IsOfNullableType(b));  // output: False

bool IsOfNullableType<T>(T o)
{
    var type = typeof(T);
    return Nullable.GetUnderlyingType(type) != null;
}

注意

このセクションで説明されているメソッドは、null 許容参照型の場合には適用されません。The methods described in this section are not applicable in the case of nullable reference types.

C# 言語仕様C# language specification

詳細については、「C# 言語仕様」の次のセクションを参照してください。For more information, see the following sections of the C# language specification:

関連項目See also