null 許容値型: C# の基礎

Tip

この記事は、少なくとも 1 つのプログラミング言語を知り、C# を学習している開発者向けの 基礎 セクションの一部です。 プログラミングを初めて使用する場合は、最初に「 はじめ に」チュートリアルから始めてください。 詳細については、言語リファレンスの「null 許容値型」を参照してください。

null 許容値型T?は、基になる値型Tのすべての値に加えて、追加のnull値を表します。 int?型の変数は、"値なし" を表す任意の整数またはnullを保持します。

intboolDateTimeなどの値型は、既定ではnullを保持できません。 この動作は効率的であり、多くのエラーを防ぎます。 ただし、この制限により、値が本当に存在しない場合に問題が発生します。 一般的なシナリオは、データベースからの読み取りです。整数列に数値が含まれている場合もあれば、値がまったく含まない場合もあります (SQL ではNULL )。 プレーンな int はその不在を表すことはできませんが、 int? できます。

null 許容値型を宣言する

?を任意の値型に追加して null 許容にします。

int?    age      = null;    // integer with no value yet
double? price    = 9.99;    // nullable double with a value
bool?   isActive = null;    // boolean with no value

age = 30;                   // assign a value later

int?[] scores = [100, null, 85, null, 72]; // array with absent entries

nullable 値型の既定値は null であり、基になる型の既定値ではありません。

値が存在するかどうかを確認する

null 許容値型を確認してその値を抽出する推奨される方法は、 型パターンを使用することです。

int? temperature = 72;

if (temperature is int degrees)
{
    Console.WriteLine($"Temperature is {degrees}°F.");
}
else
{
    Console.WriteLine("Temperature is not recorded.");
}
// Output: Temperature is 72°F.

is int degrees パターンは、temperatureが null 以外の場合にのみ一致し、値をdegreesに同時にバインドします。 null チェックと値抽出の両方を 1 つの手順で取得します。

または、 HasValue プロパティと Value プロパティを使用します。

int? count = 42;

if (count.HasValue)
{
    Console.WriteLine($"Count is {count.Value}.");
}
else
{
    Console.WriteLine("Count has no value.");
}
// Output: Count is 42.

新しいコードの is T value パターンを優先します。 一致したブランチにスコープされた新しい null 非許容変数を導入され、意図がより明確になります。また、null チェックの外側で、Value を誤使用し、InvalidOperationException がスローされる可能性が排除されます。

nullと直接比較することもできます。

int? quantity = null;

if (quantity != null)
{
    Console.WriteLine($"Quantity: {quantity.Value}");
}
else
{
    Console.WriteLine("Quantity is not set.");
}
// Output: Quantity is not set.

フォールバックを使用して値を取得する

nullable から non-nullable 値が必要な場合は、GetValueOrDefault または null 合体 ?? 演算子を使用します。

int? rating = null;

int result1 = rating.GetValueOrDefault();    // 0 (default for int)
int result2 = rating.GetValueOrDefault(-1);  // -1 (specified fallback)

Console.WriteLine(result1); // 0
Console.WriteLine(result2); // -1

rating = 5;
int result3 = rating.GetValueOrDefault(-1);  // 5 (actual value)
Console.WriteLine(result3); // 5

??演算子は、多くの場合、インラインでよりクリーンです。

int? priority = null;

int effective = priority ?? 0;  // 0 because priority is null
Console.WriteLine(effective);   // 0

priority  = 3;
effective = priority ?? 0;      // 3 because priority has a value
Console.WriteLine(effective);   // 3

どちらの方法でも、実際の値が存在する場合は実際の値が返され、存在しない場合は指定したフォールバックが返されます。

null 許容値型の算術演算

null 許容値型の算術演算子と比較演算子は持ち上げられます。いずれかのオペランドがnullである場合、結果はエラーではなくnullとなります。

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

int? sum     = a + b;   // both non-null: result is 30
int? product = a * c;   // one operand is null: result is null

Console.WriteLine(sum);               // 30
Console.WriteLine(product.HasValue);  // False — null propagates through arithmetic

Null は、既定で算術演算を通じて伝達されます。 null の結果がさらにカスケードされないようにするには、計算に使用する前に、 ?? または GetValueOrDefault を使用して値を抽出します。

こちらも参照ください