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?
変数には、true
、false
、null
の 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 can also 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 value 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:
Nullable<T>.HasValue は、null 許容値型のインスタンスに、基になる型の値が含まれるかどうかを示します。Nullable<T>.HasValue indicates whether an instance of a nullable value type has a value of its underlying type.
HasValue が
true
の場合、Nullable<T>.Value は基になる型の値を取得します。Nullable<T>.Value gets the value of an underlying type if HasValue istrue
. HasValue がfalse
の場合、Value プロパティは InvalidOperationException をスローします。If HasValue isfalse
, the Value property throws an InvalidOperationException.
次の例では、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 can also 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 can also 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 can also 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 tonull
null
未満でもないことを示しますnor less thannull
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
です。それ以外の場合は、オペランドに含まれる値が比較されます。For the equality operator ==
, if both operands are null
, the result is true
, if only one of the operands is null
, the result is false
; otherwise, the contained values of operands are compared.
非等値演算子 !=
では、両方のオペランドが null
の場合、結果は false
になります。一方のオペランドだけが null
の場合、結果は true
です。それ以外の場合は、オペランドに含まれる値が比較されます。For the inequality operator !=
, if both operands are null
, the result is false
, if only one of the operands is null
, the result is true
; otherwise, the contained values of operands are compared.
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:
- HasValue が
false
を返した場合は、null 参照が生成されます。If HasValue returnsfalse
, the null reference is produced. - HasValue が
true
を返した場合は、Nullable<T> のインスタンスではなく、基になる値型T
の対応する値がボックス化されます。If HasValue returnstrue
, the corresponding value of the underlying value typeT
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")} value type");
Console.WriteLine($"int is {(IsNullable(typeof(int)) ? "nullable" : "non-nullable")} value type");
bool IsNullable(Type type) => Nullable.GetUnderlyingType(type) != null;
// Output:
// int? is nullable value type
// int is non-nullable value 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:
- Null 許容型Nullable types
- リフト演算子Lifted operators
- 暗黙の null 許容変換Implicit nullable conversions
- 明示的な null 許容変換Explicit nullable conversions
- リフト変換演算子Lifted conversion operators