C#のnullable intとは?int?の使い方・null判定・変換エラーを初心者向けに解説

はじめに

C#で数値を扱うとき、もっともよく使う型のひとつがintです。intは整数を入れるための型ですが、通常のintにはnullを代入できません。

しかし実際の開発では、「値がまだ入力されていない」「データベース上ではNULLになっている」「APIレスポンスで数値項目が省略されることがある」といった場面があります。このようなときに使うのが、nullable int、つまりint?です。

この記事では、C#のnullable intとは何か、int?の基本的な使い方、null判定、int?からintへの変換、stringからnullable intへの変換方法、よくあるエラーと安全な書き方を初心者向けに解説します。

1. C#のnullable int(int?)とは?

1-1. nullable intは「nullを入れられるint型」

C#のnullable intとは、簡単にいうと「nullを入れられるint型」です。

通常のintには整数しか代入できません。

C#
int number = 10;

一方で、int?を使うと整数だけでなくnullも代入できます。

C#
int? number = 10;
int? emptyNumber = null;

このint?が、C#におけるnullable intです。

nullは「値が存在しない」という意味を表します。つまりint?は、「整数が入っているかもしれないし、値がないかもしれない」状態を表現できる型です。

1-2. intとint?の違い

intint?の大きな違いは、nullを代入できるかどうかです。

C#
int a = 0;      // OK
int b = null; // エラー

int? c = 0; // OK
int? d = null; // OK

intは必ず数値を持ちます。未入力や不明な値を表したい場合でも、0などの数値を入れる必要があります。

しかし、0は「値がない」という意味ではありません。たとえば年齢が0の場合、それは「0歳」という意味です。一方でnullは「年齢が未入力」「年齢が不明」という意味を表せます。

そのため、値が存在しない可能性がある整数にはint?を使うのが自然です。

1-3. int?はNullable<int>の省略記法

int?は、実はNullable<int>の省略記法です。

以下の2つは同じ意味です。

C#
int? age = null;

Nullable<int> score = null;

Nullable<T>は、値型にnullを扱えるようにするための仕組みです。intdoubleboolDateTimeなどの値型は、通常そのままではnullを代入できません。

たとえば次のように書けます。

C#
double? price = null;
bool? isActive = null;
DateTime? birthday = null;

int?Nullable<int>より短く読みやすいため、実務ではint?の書き方がよく使われます。

1-4. なぜintにnullを入れたい場面があるのか

プログラムでは、数値が必ず存在するとは限りません。

たとえば、次のようなケースがあります。

C#
int? age = null;       // 年齢が未入力
int? score = null; // テストを未受験
int? userId = null; // ユーザーIDがまだ発行されていない

このような値を通常のintで表そうとすると、仮の値として0-1を使うことがあります。

C#
int age = -1; // 未入力を表すつもり

しかし、この書き方は意味がわかりにくく、バグの原因になりやすいです。-1が本当に未入力なのか、特別な意味を持つ値なのかがコードから判断しづらいからです。

int?を使えば、「値がない」という状態をnullとして明確に表現できます。

C#
int? age = null;

2. int?の基本的な使い方

2-1. int?の宣言と代入方法

int?は次のように宣言します。

C#
int? number;

宣言と同時に値を代入することもできます。

C#
int? number = 100;

int?には整数値またはnullを代入できます。

C#
int? value1 = 10;
int? value2 = null;

通常のintと似ていますが、nullを扱える点が大きな違いです。

2-2. nullを代入する書き方

int?には、次のようにnullを代入できます。

C#
int? count = null;

あとからnullを代入することも可能です。

C#
int? count = 5;

count = null;

このように、値がなくなった状態や未設定の状態を表したいときにnullを使います。

たとえば、入力フォームで年齢が未入力だった場合は、次のように表現できます。

C#
int? age = null;

2-3. 通常のint値を代入する書き方

int?には通常の整数値もそのまま代入できます。

C#
int? age = 25;

int型の変数をint?に代入することもできます。

C#
int number = 10;
int? nullableNumber = number;

この変換は暗黙的に行われるため、特別なキャストは不要です。

つまり、intからint?への変換は安全に行えます。

2-4. Nullable<int>として書く場合との違い

int?Nullable<int>は同じ意味です。

C#
int? a = null;
Nullable<int> b = null;

どちらを使っても動作は同じです。

ただし、一般的にはint?のほうが短く、読みやすいためよく使われます。

C#
int? age = null;

Nullable<int>と書くと、型の仕組みを明示できますが、日常的なコードでは少し長く感じられます。

C#
Nullable<int> age = null;

初心者のうちは、int?Nullable<int>の省略形だと理解しておけば十分です。

3. nullable intのnull判定方法

3-1. == nullで判定する

int?nullかどうかを調べるには、== nullを使えます。

C#
int? age = null;

if (age == null)
{
Console.WriteLine("年齢は未入力です");
}

この書き方は直感的でわかりやすいため、初心者にもおすすめです。

int?に値が入っていない場合、age == nulltrueになります。

C#
int? age = null;

Console.WriteLine(age == null); // True

3-2. != nullで値があるか判定する

値が入っているかどうかを確認したい場合は、!= nullを使います。

C#
int? age = 20;

if (age != null)
{
Console.WriteLine("年齢が入力されています");
}

値がある場合だけ処理したいときによく使います。

C#
int? score = 80;

if (score != null)
{
Console.WriteLine($"点数は{score}点です");
}

ただし、scoreはこの時点でも型としてはint?です。通常のintとして扱いたい場合は、変換方法に注意が必要です。

3-3. HasValueで判定する

int?にはHasValueというプロパティがあります。

HasValueは、値が入っていればtruenullであればfalseを返します。

C#
int? age = 30;

if (age.HasValue)
{
Console.WriteLine("値があります");
}

nullの場合はfalseになります。

C#
int? age = null;

Console.WriteLine(age.HasValue); // False

age != nullage.HasValueは、ほぼ同じ意味で使えます。

C#
if (age != null)
{
// 値がある場合
}

if (age.HasValue)
{
// 値がある場合
}

3-4. Valueを使うときの注意点

int?に入っている値を取り出すには、Valueプロパティを使えます。

C#
int? age = 25;

int actualAge = age.Value;

ただし、Valuenullの状態で使うとエラーになります。

C#
int? age = null;

int actualAge = age.Value; // エラー

このとき発生する代表的なエラーが、Nullable object must have a valueです。

そのため、Valueを使う前には必ず値があるか確認しましょう。

C#
int? age = null;

if (age.HasValue)
{
int actualAge = age.Value;
Console.WriteLine(actualAge);
}
else
{
Console.WriteLine("年齢は未入力です");
}

3-5. GetValueOrDefaultでデフォルト値を取得する

GetValueOrDefaultを使うと、int?nullの場合にデフォルト値を取得できます。

C#
int? count = null;

int result = count.GetValueOrDefault();

Console.WriteLine(result); // 0

int?の場合、引数なしのGetValueOrDefault()は、nullのときに0を返します。

任意のデフォルト値を指定することもできます。

C#
int? count = null;

int result = count.GetValueOrDefault(-1);

Console.WriteLine(result); // -1

nullのときに特定の値を使いたい場合に便利です。

C#
int? score = null;

int displayScore = score.GetValueOrDefault(0);

ただし、null0は本来別の意味です。デフォルト値に置き換えてよい場面かどうかは、よく考える必要があります。

4. int?からintへ変換する方法

4-1. 明示的キャストで変換する

int?からintへ変換するには、明示的キャストを使う方法があります。

C#
int? nullableNumber = 10;

int number = (int)nullableNumber;

値が入っている場合は問題なく変換できます。

しかし、nullableNumbernullの場合はエラーになります。

C#
int? nullableNumber = null;

int number = (int)nullableNumber; // エラー

そのため、明示的キャストを使う場合は、事前にnullでないことを確認する必要があります。

C#
int? nullableNumber = 10;

if (nullableNumber != null)
{
int number = (int)nullableNumber;
Console.WriteLine(number);
}

4-2. Valueプロパティで変換する

Valueプロパティを使ってint?からintへ変換することもできます。

C#
int? nullableNumber = 20;

int number = nullableNumber.Value;

これも値がある場合は問題ありません。

ただし、nullの場合はエラーになります。

C#
int? nullableNumber = null;

int number = nullableNumber.Value; // エラー

安全に使うには、HasValueで確認してからValueを使います。

C#
int? nullableNumber = 20;

if (nullableNumber.HasValue)
{
int number = nullableNumber.Value;
Console.WriteLine(number);
}

Valueは便利ですが、安易に使うと実行時エラーの原因になります。

4-3. ??演算子でnull時の値を指定する

int?からintへ安全に変換する方法として、??演算子があります。

??演算子は、左側がnullでなければその値を使い、nullであれば右側の値を使います。

C#
int? nullableNumber = null;

int number = nullableNumber ?? 0;

Console.WriteLine(number); // 0

値がある場合は、その値が使われます。

C#
int? nullableNumber = 15;

int number = nullableNumber ?? 0;

Console.WriteLine(number); // 15

この書き方はシンプルで安全です。

C#
int? age = null;

int displayAge = age ?? -1;

nullの場合にどの値として扱うかが明確な場合は、??演算子を使うとよいでしょう。

4-4. GetValueOrDefaultで安全に変換する

GetValueOrDefaultを使っても、int?からintへ安全に変換できます。

C#
int? nullableNumber = null;

int number = nullableNumber.GetValueOrDefault();

Console.WriteLine(number); // 0

任意のデフォルト値を指定することもできます。

C#
int? nullableNumber = null;

int number = nullableNumber.GetValueOrDefault(100);

Console.WriteLine(number); // 100

??演算子と似た用途で使えます。

C#
int number1 = nullableNumber ?? 100;
int number2 = nullableNumber.GetValueOrDefault(100);

どちらを使ってもよいですが、一般的には??演算子のほうが短く読みやすいです。

4-5. nullの可能性があるときに避けるべき変換

nullの可能性があるint?を、確認せずにintへ変換するのは避けましょう。

避けるべき例は次のとおりです。

C#
int? value = null;

int number1 = (int)value;
int number2 = value.Value;

どちらもvaluenullの場合にエラーになります。

安全に書くなら、次のようにします。

C#
int? value = null;

int number = value ?? 0;

または、nullの場合は別処理にします。

C#
int? value = null;

if (value.HasValue)
{
int number = value.Value;
Console.WriteLine(number);
}
else
{
Console.WriteLine("値がありません");
}

int?intへ変換するときは、「nullだったらどうするか」を必ず考えることが重要です。

5. stringからnullable intへ変換する方法

5-1. int.Parseで変換する場合の注意点

文字列を整数に変換するには、int.Parseを使えます。

C#
string text = "123";

int number = int.Parse(text);

ただし、int.Parseは変換できない文字列を渡すとエラーになります。

C#
string text = "abc";

int number = int.Parse(text); // FormatException

空文字でもエラーになります。

C#
string text = "";

int number = int.Parse(text); // FormatException

int.Parseは、必ず数値の文字列が入っているとわかっている場合には使えます。

しかし、入力フォームやCSVなど、どんな文字列が来るかわからない場面では注意が必要です。

5-2. int.TryParseで安全に変換する

安全に文字列を整数へ変換するには、int.TryParseを使います。

C#
string text = "123";

if (int.TryParse(text, out int number))
{
Console.WriteLine($"変換成功: {number}");
}
else
{
Console.WriteLine("変換できませんでした");
}

TryParseは、変換に成功するとtrueを返し、変換後の値をout引数に入れます。

変換に失敗しても例外は発生しません。

C#
string text = "abc";

bool success = int.TryParse(text, out int number);

Console.WriteLine(success); // False

ユーザー入力のように不正な値が入る可能性がある場合は、int.Parseよりint.TryParseを使うのが安全です。

5-3. 空文字やnullをint?に変換する実装例

空文字やnullint?に変換したい場合は、次のようなメソッドを作ると便利です。

C#
static int? ToNullableInt(string? text)
{
if (string.IsNullOrWhiteSpace(text))
{
return null;
}

if (int.TryParse(text, out int number))
{
return number;
}

return null;
}

使い方は次のとおりです。

C#
int? value1 = ToNullableInt("123"); // 123
int? value2 = ToNullableInt(""); // null
int? value3 = ToNullableInt(null); // null
int? value4 = ToNullableInt("abc"); // null

この実装では、空文字、空白、null、数値に変換できない文字列をすべてnullとして扱っています。

不正な文字列の場合はエラーにしたい場合、次のように例外を投げる設計もあります。

C#
static int? ToNullableInt(string? text)
{
if (string.IsNullOrWhiteSpace(text))
{
return null;
}

if (int.TryParse(text, out int number))
{
return number;
}

throw new FormatException("数値に変換できない文字列です");
}

仕様に応じて、nullにするのかエラーにするのかを決めましょう。

5-4. 入力フォームやCSV読み込みでよくある使い方

入力フォームでは、年齢や点数などが未入力になることがあります。

C#
string? inputAge = "";

int? age = ToNullableInt(inputAge);

この場合、未入力を0ではなくnullとして扱えます。

CSV読み込みでも同じです。

C#
string csvAge = "";      // 年齢列が空
string csvScore = "85"; // 点数列に値あり

int? age = ToNullableInt(csvAge);
int? score = ToNullableInt(csvScore);

結果は次のようになります。

C#
age   // null
score // 85

データベースに保存する場合も、nullとして扱えば「未入力」という意味を保てます。

C#
if (age == null)
{
Console.WriteLine("年齢は未入力です");
}

6. nullable intでよくあるエラーと原因

6-1. Nullable object must have a valueの原因

Nullable object must have a valueは、int?nullなのにValueを使ったときによく発生します。

C#
int? age = null;

int actualAge = age.Value; // エラー

Valueは中身の値を取り出すためのプロパティですが、nullの場合は取り出す値がありません。

このエラーを防ぐには、HasValueで確認します。

C#
int? age = null;

if (age.HasValue)
{
int actualAge = age.Value;
Console.WriteLine(actualAge);
}
else
{
Console.WriteLine("値がありません");
}

または、??演算子を使います。

C#
int? age = null;

int actualAge = age ?? 0;

6-2. int?をintに暗黙的に変換できないエラー

次のコードはエラーになります。

C#
int? nullableNumber = 10;

int number = nullableNumber; // エラー

int?にはnullが入る可能性があります。そのため、C#は自動的にintへ変換できません。

安全に変換するには、??演算子などを使います。

C#
int? nullableNumber = 10;

int number = nullableNumber ?? 0;

または、値があることを確認してから変換します。

C#
if (nullableNumber.HasValue)
{
int number = nullableNumber.Value;
}

intからint?への変換は自動でできますが、int?からintへの変換は注意が必要です。

C#
int number = 10;
int? nullableNumber = number; // OK

逆方向は、null対策が必要です。

6-3. nullをintに代入できないエラー

通常のintにはnullを代入できません。

C#
int age = null; // エラー

nullを扱いたい場合は、int?を使います。

C#
int? age = null; // OK

この違いは初心者がつまずきやすいポイントです。

intは「必ず整数がある」場合に使います。

C#
int count = 0;

int?は「整数がない可能性がある」場合に使います。

C#
int? count = null;

6-4. Parse失敗によるFormatException

int.Parseで数値ではない文字列を変換しようとすると、FormatExceptionが発生します。

C#
string text = "abc";

int number = int.Parse(text); // FormatException

空文字でも同じです。

C#
string text = "";

int number = int.Parse(text); // FormatException

外部から受け取った文字列を変換する場合は、int.TryParseを使うほうが安全です。

C#
string text = "abc";

if (int.TryParse(text, out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("数値ではありません");
}

TryParseを使えば、変換に失敗してもプログラムが止まりにくくなります。

6-5. エラーを防ぐ安全な書き方

nullable intのエラーを防ぐには、次の考え方が重要です。

まず、int?からintへ変換するときは、必ずnullの場合を考えます。

C#
int? value = null;

int number = value ?? 0;

次に、Valueを使う場合は事前にHasValueを確認します。

C#
if (value.HasValue)
{
int number = value.Value;
}

文字列から変換するときは、int.Parseよりint.TryParseを優先します。

C#
string input = "123";

int? number = int.TryParse(input, out int result)
? result
: null;

また、空文字やnullを扱う場合は、先にチェックします。

C#
string? input = "";

int? number = string.IsNullOrWhiteSpace(input)
? null
: int.TryParse(input, out int result) ? result : null;

安全な書き方を習慣にすると、Nullable object must have a valueFormatExceptionなどのエラーを減らせます。

7. nullable intを使う実践例

7-1. 未入力の年齢や点数を扱う

入力フォームで年齢が未入力の場合、int?を使うと自然に表現できます。

C#
int? age = null;

年齢が入力されている場合は数値を代入します。

C#
age = 25;

表示するときは、nullかどうかを判定します。

C#
if (age.HasValue)
{
Console.WriteLine($"年齢: {age.Value}歳");
}
else
{
Console.WriteLine("年齢は未入力です");
}

テストの点数でも同じです。

C#
int? score = null;

if (score == null)
{
Console.WriteLine("未受験です");
}
else
{
Console.WriteLine($"点数: {score}点");
}

0点未受験は意味が違います。int?を使うことで、この違いを正しく表現できます。

7-2. データベースのNULL値を扱う

データベースでは、数値カラムがNULLになることがあります。

たとえば、AgeカラムがNULL許可の場合、C#側ではint?として扱うのが自然です。

C#
public class User
{
public int Id { get; set; }
public int? Age { get; set; }
}

Ageが未登録の場合はnullになります。

C#
User user = new User
{
Id = 1,
Age = null
};

表示するときは、null判定を行います。

C#
if (user.Age == null)
{
Console.WriteLine("年齢未登録");
}
else
{
Console.WriteLine($"{user.Age}歳");
}

データベースのNULLとC#のnullを対応させることで、データの意味を保ったまま扱えます。

7-3. APIレスポンスの省略可能な数値を扱う

APIレスポンスでは、数値項目が省略されたり、nullで返ってきたりすることがあります。

たとえば、次のようなレスポンスを考えます。

JSON
{
"id": 1,
"name": "Taro",
"age": null
}

この場合、C#のモデルではAgeint?にします。

C#
public class UserResponse
{
public int Id { get; set; }
public string Name { get; set; } = "";
public int? Age { get; set; }
}

Ageが存在しない可能性があるなら、通常のintではなくint?にすることで安全に扱えます。

C#
if (response.Age.HasValue)
{
Console.WriteLine($"年齢: {response.Age.Value}");
}
else
{
Console.WriteLine("年齢情報はありません");
}

外部APIを扱うときは、値が必ず返るとは限らないため、nullable intがよく使われます。

7-4. LINQや条件分岐でint?を使う

int?はLINQや条件分岐でもよく使います。

たとえば、年齢が入力されているユーザーだけを抽出する場合です。

C#
var usersWithAge = users.Where(user => user.Age.HasValue);

年齢が20歳以上のユーザーだけを抽出する場合は、次のように書けます。

C#
var adults = users.Where(user => user.Age >= 20);

ただし、Agenullの場合、比較結果はfalseのように扱われます。明示的に書くなら次のようにできます。

C#
var adults = users.Where(user => user.Age.HasValue && user.Age.Value >= 20);

nullの場合にデフォルト値を使って並び替えることもできます。

C#
var orderedUsers = users.OrderBy(user => user.Age ?? int.MaxValue);

この例では、Agenullのユーザーを最後に並べるためにint.MaxValueを使っています。

8. nullable intを使うときの注意点

8-1. nullと0は別の意味として扱う

int?を使ううえで重要なのは、null0を混同しないことです。

C#
int? score1 = null; // 未受験
int? score2 = 0; // 0点

この2つはまったく違う意味です。

nullは「値がない」ことを表します。0は「数値として0である」ことを表します。

年齢でも同じです。

C#
int? age1 = null; // 未入力
int? age2 = 0; // 0歳

nullを安易に0へ変換すると、意味が変わってしまうことがあります。

C#
int displayAge = age1 ?? 0;

この書き方が悪いわけではありませんが、「未入力」を「0歳」と表示してよいのかは確認が必要です。

8-2. 安易にValueを使わない

Valueは便利ですが、nullの場合にエラーになります。

C#
int? value = null;

int number = value.Value; // エラー

そのため、Valueを使うときは必ずHasValueを確認しましょう。

C#
if (value.HasValue)
{
int number = value.Value;
}

ただし、多くの場合は??演算子のほうが簡潔です。

C#
int number = value ?? 0;

「値がない場合はどうするか」が明確なときは、??を使うと読みやすくなります。

8-3. null許容参照型との違いを理解する

C#には、int?のようなnullable値型とは別に、null許容参照型という仕組みもあります。

たとえば、次のような書き方です。

C#
string? name = null;

int?string?は見た目が似ていますが、意味する仕組みは少し違います。

intは値型です。通常はnullを持てないため、Nullable<int>、つまりint?を使ってnullを扱えるようにします。

一方、stringは参照型です。string?は「この参照型はnullになる可能性がある」という注釈として使われます。

C#
int? age = null;       // Nullable<int>
string? name = null; // null許容参照型

初心者のうちは、int?は「nullを入れられるint」、string?は「nullの可能性を明示したstring」と理解しておくとよいでしょう。

8-4. 可読性を下げないための書き方

int?を使うと便利ですが、null判定や変換が多すぎるとコードが読みにくくなることがあります。

読みにくい例です。

C#
int result = value.HasValue ? value.Value : 0;

この場合は、??演算子を使うとすっきりします。

C#
int result = value ?? 0;

また、複雑な変換処理はメソッドに分けると読みやすくなります。

C#
static int? ToNullableInt(string? text)
{
if (string.IsNullOrWhiteSpace(text))
{
return null;
}

return int.TryParse(text, out int number) ? number : null;
}

呼び出し側はシンプルになります。

C#
int? age = ToNullableInt(input);

nullable intを使うときは、ただ動くコードを書くのではなく、「nullの意味が読み取れるか」「安全に変換できているか」を意識しましょう。

9. C#のnullable intに関するよくある質問

9-1. int?とNullable<int>はどちらを使うべき?

基本的にはint?を使うのがおすすめです。

C#
int? age = null;

int?Nullable<int>の省略記法なので、動作は同じです。

C#
Nullable<int> age = null;

どちらも同じ意味ですが、int?のほうが短く、一般的なC#コードでよく使われます。

ただし、学習目的で仕組みを説明するときや、ジェネリック型として明示したいときはNullable<int>と書くこともあります。

通常の開発では、読みやすさを優先してint?を使うとよいでしょう。

9-2. int?に計算や比較はできる?

int?でも計算や比較はできます。

C#
int? a = 10;
int? b = 20;

int? sum = a + b;

Console.WriteLine(sum); // 30

ただし、どちらかがnullの場合、結果もnullになります。

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

int? sum = a + b;

Console.WriteLine(sum); // null

比較もできます。

C#
int? age = 20;

if (age >= 18)
{
Console.WriteLine("成人です");
}

ただし、agenullの場合、条件は成立しません。

より明確に書くなら、次のようにします。

C#
if (age.HasValue && age.Value >= 18)
{
Console.WriteLine("成人です");
}
else
{
Console.WriteLine("年齢が未入力、または18歳未満です");
}

9-3. int?の初期値は何?

int?の初期値はnullです。

クラスのプロパティとして宣言した場合、明示的に代入しなければnullになります。

C#
public class User
{
public int? Age { get; set; }
}

この場合、Ageの初期値はnullです。

C#
User user = new User();

Console.WriteLine(user.Age == null); // True

ローカル変数の場合は、使用前に値を代入する必要があります。

C#
int? age;
age = null;

Console.WriteLine(age == null);

int?は「値がない状態」を表せるため、初期値としてnullを使う場面が多いです。

9-4. nullの場合だけ別処理にするには?

nullの場合だけ別処理にしたい場合は、== nullを使うとわかりやすいです。

C#
int? age = null;

if (age == null)
{
Console.WriteLine("年齢は未入力です");
}
else
{
Console.WriteLine($"年齢は{age}歳です");
}

HasValueを使うこともできます。

C#
if (!age.HasValue)
{
Console.WriteLine("年齢は未入力です");
}
else
{
Console.WriteLine($"年齢は{age.Value}歳です");
}

nullの場合にデフォルト値を使うだけなら、??演算子が便利です。

C#
int displayAge = age ?? 0;

ただし、null0として扱ってよいかどうかは、仕様に合わせて判断しましょう。

まとめ

C#のnullable intは、nullを入れられる整数型です。通常のintにはnullを代入できませんが、int?を使うことで「値があるかもしれないし、ないかもしれない」という状態を表現できます。

int?Nullable<int>の省略記法です。

C#
int? age = null;
Nullable<int> score = null;

int?のnull判定には、== null!= nullHasValueなどを使います。

C#
if (age == null)
{
Console.WriteLine("未入力です");
}

if (age.HasValue)
{
Console.WriteLine(age.Value);
}

ただし、Valuenullのときに使うとNullable object must have a valueというエラーになるため注意が必要です。

int?からintへ変換する場合は、??演算子やGetValueOrDefaultを使うと安全です。

C#
int number = age ?? 0;

文字列からnullable intへ変換する場合は、int.Parseではなくint.TryParseを使うと、変換エラーを防ぎやすくなります。

C#
int? number = int.TryParse(input, out int result) ? result : null;

nullable intを使うときは、null0を別の意味として扱うことが大切です。nullは「値がない」、0は「数値として0」です。

未入力の年齢、未受験の点数、データベースのNULL値、APIレスポンスの省略可能な数値など、値が存在しない可能性がある場面ではint?を使うと、意味が明確で安全なコードを書けます。