C#の数値変換を完全解説|Parse・TryParse・Convertの違いとエラーを防ぐ安全な使い分け

はじめに

C#で開発していると、文字列を数値に変換する場面は非常に多くあります。たとえば、画面のテキストボックスに入力された値をintに変換する、CSVから読み込んだ金額をdecimalに変換する、APIから返ってきた数値文字列をdoubleに変換する、といったケースです。

しかし、C#の数値変換にはParseTryParseConvert、キャストなど複数の方法があり、使い分けを誤るとFormatExceptionOverflowExceptionなどの例外が発生します。

この記事では、C#の数値変換について、基本から実務での安全な使い分けまで解説します。特に、ParseTryParseConvertの違いを理解し、エラーを防ぐ書き方を身につけることを目的としています。

1. C#の数値変換でよくある悩みとこの記事で解決できること

1-1. 文字列をint・double・decimalに変換したい

C#では、文字列を数値に変換する代表的な方法として、各数値型に用意されているParseTryParseを使用します。Microsoftの公式ドキュメントでも、数値型には文字列を数値型へ変換するためのParseTryParseが用意されていると説明されています。

C#
string text = "123";

int number = int.Parse(text);
double doubleValue = double.Parse("123.45");
decimal decimalValue = decimal.Parse("123.45");

このように、文字列が正しい数値形式であれば簡単に変換できます。

ただし、実務では常に正しい値が入っているとは限りません。空文字、null、カンマ付きの数値、不正な文字列、範囲外の値などを考慮する必要があります。

1-2. Parse・TryParse・Convertの違いが分からない

C#の数値変換で混乱しやすいのが、ParseTryParseConvertの違いです。

簡単にいうと、次のように使い分けます。

方法特徴主な用途
Parse変換できないと例外が発生する値が必ず正しいと分かっている場合
TryParse成功・失敗をboolで判定できるユーザー入力や外部データの変換
Convertnullの扱いなどがParseと異なる汎用的な型変換

実務では、エラーを避けるためにTryParseを使う場面が最も多くなります。

1-3. FormatExceptionやOverflowExceptionを防ぎたい

FormatExceptionは、文字列の形式が数値として正しくない場合に発生します。

C#
int value = int.Parse("abc"); // FormatException

OverflowExceptionは、変換先の型に収まらない値を変換しようとした場合に発生します。

C#
int value = int.Parse("999999999999"); // OverflowException

これらの例外は、TryParseを使うことで事前に防げます。

C#
if (int.TryParse("abc", out int value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("数値に変換できません。");
}

1-4. null・空文字・不正な入力を安全に処理したい

ユーザー入力や外部ファイルの値には、null、空文字、不正な文字列が含まれることがあります。

C#
string? input = null;

このような値に対してParseを使うと例外が発生する可能性があります。一方、TryParseであれば例外を出さずに失敗として処理できます。

C#
string? input = null;

if (int.TryParse(input, out int result))
{
Console.WriteLine(result);
}
else
{
Console.WriteLine("入力値が不正です。");
}

安全な数値変換を行うには、「変換できない可能性がある値にはTryParseを使う」と覚えておくとよいでしょう。

1-5. 実務でどの変換方法を選ぶべきか判断したい

実務での基本方針は次の通りです。

状況推奨する方法
ユーザー入力を変換するTryParse
CSVやAPIなど外部データを変換するTryParse
固定値や内部的に保証された文字列を変換するParse
nullを0として扱いたいConvert
数値型同士を変換するキャストまたはConvert

特に、画面入力、ファイル読み込み、APIレスポンスなど、外部から入ってくる値は信用せず、TryParseで安全に判定するのが基本です。

2. C#の数値変換の基本

2-1. 数値変換とは何か

C#の数値変換とは、ある値を別の数値型に変える処理のことです。

たとえば、次のような変換があります。

C#
string text = "100";
int number = int.Parse(text);

これは、文字列"100"を整数型の100に変換しています。

また、数値型同士の変換も数値変換に含まれます。

C#
int intValue = 100;
double doubleValue = intValue;

この例では、int型の値をdouble型に変換しています。

2-2. 文字列から数値への変換

文字列から数値への変換では、主に次のメソッドを使います。

C#
int.Parse("123");
int.TryParse("123", out int result);
Convert.ToInt32("123");

それぞれ同じように見えますが、エラー時の動作やnullの扱いが異なります。

C#
string text = "123";

int a = int.Parse(text);

if (int.TryParse(text, out int b))
{
Console.WriteLine(b);
}

int c = Convert.ToInt32(text);

値が確実に正しいならParseでも問題ありませんが、入力値が不確実な場合はTryParseを使うのが安全です。

2-3. 数値型同士の変換

C#では、intからdoubleのように安全に変換できる場合は、自動的に変換できます。

C#
int intValue = 100;
double doubleValue = intValue;

一方、doubleからintのように小数点以下が失われる可能性がある変換では、明示的なキャストが必要です。

C#
double doubleValue = 123.45;
int intValue = (int)doubleValue;

Console.WriteLine(intValue); // 123

C#では数値型同士に暗黙的変換と明示的変換があり、明示的変換にはキャスト式を使用します。

2-4. 暗黙的変換と明示的変換の違い

暗黙的変換は、データの損失が起きにくい変換で、C#が自動的に行います。

C#
int intValue = 10;
long longValue = intValue;
double doubleValue = intValue;

intからlongdoubleへの変換は、通常値を表現できる範囲が広がるため、暗黙的に変換できます。

一方、明示的変換は、データの損失や範囲外の可能性があるため、開発者がキャストを指定する必要があります。

C#
double doubleValue = 10.9;
int intValue = (int)doubleValue;

Console.WriteLine(intValue); // 10

この場合、小数点以下は切り捨てられます。

2-5. 型変換で注意すべき桁あふれと精度落ち

数値変換で注意すべきポイントは、桁あふれと精度落ちです。

桁あふれは、変換先の型で表現できる範囲を超えた場合に発生します。

C#
long longValue = 3000000000;
int intValue = (int)longValue;

このような変換では、期待しない値になる可能性があります。範囲を厳密にチェックしたい場合は、checkedを使います。

C#
long longValue = 3000000000;

try
{
int intValue = checked((int)longValue);
}
catch (OverflowException)
{
Console.WriteLine("intの範囲を超えています。");
}

精度落ちは、decimalからdoubledoubleからfloatなど、表現精度が異なる型へ変換するときに発生することがあります。

金額計算ではdecimal、一般的な小数計算ではdoubleを使うなど、用途に合わせて型を選ぶことが重要です。

3. Parseを使った数値変換

3-1. Parseの基本的な使い方

Parseは、文字列を指定した数値型に変換するメソッドです。

C#
string text = "100";
int value = int.Parse(text);

Console.WriteLine(value); // 100

Parseは、文字列が正しい数値形式であることを前提にしています。そのため、不正な文字列を渡すと例外が発生します。

C#
int value = int.Parse("abc"); // 例外

3-2. int.Parseで文字列を整数に変換する

int.Parseは、文字列をint型に変換します。

C#
string text = "123";
int number = int.Parse(text);

Console.WriteLine(number + 10); // 133

マイナスの値も変換できます。

C#
int value = int.Parse("-123");
Console.WriteLine(value); // -123

前後の空白は基本的に許容されます。

C#
int value = int.Parse(" 123 ");
Console.WriteLine(value); // 123

ただし、カンマ区切りの文字列は、そのままでは変換できない場合があります。

C#
int value = int.Parse("1,000"); // 環境や指定方法によっては例外

カンマを含む数値を扱う場合は、NumberStylesCultureInfoを指定します。

C#
using System.Globalization;

string text = "1,000";

int value = int.Parse(
text,
NumberStyles.AllowThousands,
CultureInfo.InvariantCulture
);

Console.WriteLine(value); // 1000

3-3. double.Parse・decimal.Parseで小数を変換する

小数を扱う場合は、double.Parsedecimal.Parseを使います。

C#
double doubleValue = double.Parse("123.45");
decimal decimalValue = decimal.Parse("123.45");

Console.WriteLine(doubleValue);
Console.WriteLine(decimalValue);

doubleは科学計算や一般的な小数計算に向いています。一方、decimalは10進数の精度を重視するため、金額計算に向いています。

C#
decimal price = decimal.Parse("1980.50");
Console.WriteLine(price);

CSVやAPIなど、数値の小数点が.で固定されているデータを扱う場合は、CultureInfo.InvariantCultureを指定すると環境差を避けやすくなります。

C#
using System.Globalization;

string text = "123.45";

decimal value = decimal.Parse(
text,
CultureInfo.InvariantCulture
);

数値の解析では、カルチャ固有の小数点記号や桁区切り記号が関係します。NumberFormatInfoには、小数点記号や桁区切り記号など、数値の書式と解析に関する情報が含まれています。

3-4. Parseで発生しやすい例外

Parseで発生しやすい例外は、主に次の3つです。

例外原因
FormatException数値として解釈できない文字列
OverflowException変換先の型の範囲を超えている
ArgumentNullExceptionnullを渡した場合

例を見てみましょう。

C#
int.Parse("abc");          // FormatException
int.Parse("999999999999"); // OverflowException
int.Parse(null); // ArgumentNullException

Parseを使う場合は、これらの例外が発生する可能性を考慮する必要があります。

C#
try
{
int value = int.Parse("abc");
}
catch (FormatException)
{
Console.WriteLine("数値形式が正しくありません。");
}
catch (OverflowException)
{
Console.WriteLine("値が範囲外です。");
}

ただし、ユーザー入力のように失敗が想定される場面で毎回例外処理を書くより、TryParseを使う方がシンプルです。

3-5. Parseを使うべき場面と避けるべき場面

Parseを使うべき場面は、値が必ず正しいと保証できる場合です。

C#
string fixedValue = "100";
int value = int.Parse(fixedValue);

たとえば、プログラム内部で固定している文字列、テストデータ、仕様上必ず数値形式になる値などです。

一方、次のような場面ではParseを避けるべきです。

避けるべき場面理由
テキストボックスの入力値ユーザーが不正な値を入力する可能性がある
CSVファイルの読み込み欠損値や不正データが含まれる可能性がある
APIレスポンス想定外の値や空文字が返る可能性がある
データベースの文字列項目過去データに不整合がある可能性がある

失敗が想定される変換では、基本的にTryParseを使いましょう。

4. TryParseを使った安全な数値変換

4-1. TryParseの基本的な使い方

TryParseは、文字列を数値に変換できるかどうかを判定し、成功した場合だけ変換結果を取得できるメソッドです。

C#
string text = "123";

if (int.TryParse(text, out int value))
{
Console.WriteLine($"変換成功: {value}");
}
else
{
Console.WriteLine("変換失敗");
}

TryParseの戻り値はboolです。

戻り値意味
true変換成功
false変換失敗

変換に成功すると、out引数に変換後の値が入ります。失敗した場合でも例外は発生しません。

4-2. TryParseがエラー対策に向いている理由

TryParseがエラー対策に向いている理由は、変換できない値を例外ではなく通常の分岐として扱えるからです。

C#
string input = "abc";

if (!int.TryParse(input, out int value))
{
Console.WriteLine("整数を入力してください。");
return;
}

Console.WriteLine(value);

この書き方であれば、ユーザーが不正な値を入力してもアプリケーションが例外で停止することを防げます。

特に、次のような値を扱うときに有効です。

入力値TryParseの結果
"123"true
"abc"false
""false
nullfalse
"999999999999"false

4-3. int.TryParseで入力値を安全に判定する

整数入力を安全に処理する例です。

C#
Console.Write("年齢を入力してください: ");
string? input = Console.ReadLine();

if (int.TryParse(input, out int age))
{
Console.WriteLine($"年齢は{age}歳です。");
}
else
{
Console.WriteLine("年齢は整数で入力してください。");
}

さらに、範囲チェックも組み合わせると実務的です。

C#
string? input = Console.ReadLine();

if (!int.TryParse(input, out int age))
{
Console.WriteLine("整数で入力してください。");
return;
}

if (age < 0 || age > 120)
{
Console.WriteLine("年齢は0〜120の範囲で入力してください。");
return;
}

Console.WriteLine($"入力された年齢: {age}");

TryParseは形式チェック、範囲チェックは別途ifで行う、と分けて考えると分かりやすくなります。

4-4. double.TryParse・decimal.TryParseの使い分け

小数を変換する場合は、用途に応じてdouble.TryParsedecimal.TryParseを使い分けます。

C#
double.TryParse("123.45", out double doubleValue);
decimal.TryParse("123.45", out decimal decimalValue);

一般的な使い分けは次の通りです。

向いている用途
double科学計算、測定値、座標、割合
decimal金額、税率、請求額、会計処理
floatメモリ使用量を抑えたい大量データ、ゲーム、グラフィックス

金額を扱う場合は、基本的にdecimalを選びます。

C#
string input = "1980.50";

if (decimal.TryParse(input, out decimal price))
{
Console.WriteLine($"価格: {price}円");
}
else
{
Console.WriteLine("価格の形式が正しくありません。");
}

CSVやAPIでは、カルチャ差による誤変換を避けるため、CultureInfo.InvariantCultureを指定するのがおすすめです。

C#
using System.Globalization;

string input = "123.45";

bool success = decimal.TryParse(
input,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out decimal value
);

if (success)
{
Console.WriteLine(value);
}

Decimal.TryParseには、スタイルやカルチャを指定して変換するオーバーロードが用意されています。

4-5. ユーザー入力やCSV読み込みでTryParseを使う例

CSVから金額を読み込む例です。

C#
using System.Globalization;

string csvValue = "1234.56";

if (decimal.TryParse(
csvValue,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out decimal amount))
{
Console.WriteLine($"金額: {amount}");
}
else
{
Console.WriteLine("CSVの金額データが不正です。");
}

複数行のCSVを処理する場合は、不正な行をスキップしたり、エラーログに記録したりします。

C#
using System.Globalization;

string[] values = { "100.50", "abc", "200.75", "" };

foreach (string value in values)
{
if (decimal.TryParse(
value,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out decimal amount))
{
Console.WriteLine($"変換成功: {amount}");
}
else
{
Console.WriteLine($"変換失敗: {value}");
}
}

外部データを扱うときは、失敗する前提でコードを書くことが重要です。

5. Convertを使った数値変換

5-1. Convert.ToInt32の基本的な使い方

Convert.ToInt32は、値をint型に変換するメソッドです。

C#
string text = "123";
int value = Convert.ToInt32(text);

Console.WriteLine(value); // 123

文字列だけでなく、doubledecimalなどの値も変換できます。

C#
double doubleValue = 123.45;
int intValue = Convert.ToInt32(doubleValue);

Console.WriteLine(intValue);

ただし、Convert.ToInt32は小数を整数に変換するときに丸め処理を行います。キャストとは挙動が違うため注意が必要です。

5-2. ConvertとParseの違い

ConvertParseの大きな違いは、nullの扱いです。

C#
string? text = null;

int value = Convert.ToInt32(text);
Console.WriteLine(value); // 0

Convert.ToInt32(null)0を返します。

一方、int.Parse(null)は例外になります。

C#
string? text = null;

int value = int.Parse(text); // ArgumentNullException

この違いは非常に重要です。

null0として扱いたい場合はConvertが便利ですが、nullを不正値として検出したい場合はTryParseなどで明示的に判定する方が安全です。

5-3. nullを変換した場合の挙動

Convertでは、nullを変換すると型に応じた既定値になります。

C#
string? text = null;

int intValue = Convert.ToInt32(text);
double doubleValue = Convert.ToDouble(text);
decimal decimalValue = Convert.ToDecimal(text);

Console.WriteLine(intValue); // 0
Console.WriteLine(doubleValue); // 0
Console.WriteLine(decimalValue); // 0

この挙動は便利な反面、入力漏れを見逃す原因にもなります。

たとえば、金額が未入力なのに0円として処理されてしまうと、業務上の不具合につながる可能性があります。

C#
string? priceText = null;

decimal price = Convert.ToDecimal(priceText);

// 未入力なのに0として処理される
Console.WriteLine(price); // 0

未入力をエラーとして扱いたい場合は、次のように明示的にチェックします。

C#
string? priceText = null;

if (string.IsNullOrWhiteSpace(priceText))
{
Console.WriteLine("金額を入力してください。");
return;
}

decimal price = Convert.ToDecimal(priceText);

5-4. Convertで発生する例外

Convertでも、不正な文字列や範囲外の値では例外が発生します。

C#
Convert.ToInt32("abc");          // FormatException
Convert.ToInt32("999999999999"); // OverflowException

null0になりますが、空文字は変換できません。

C#
Convert.ToInt32(""); // FormatException

つまり、Convertnullには強いものの、不正文字列や空文字まで安全に処理できるわけではありません。

安全性を重視する場合は、やはりTryParseを使うべきです。

5-5. Convertを使うべき場面と注意点

Convertを使うべき場面は、値の型が一定でない場合や、nullを既定値として扱いたい場合です。

C#
object value = "123";
int number = Convert.ToInt32(value);

ただし、次の点には注意が必要です。

注意点内容
null0になる未入力を見逃す可能性がある
不正文字列では例外が出る"abc"""は変換できない
小数から整数では丸められるキャストとは結果が異なる
範囲外では例外が出るintの範囲を超える値は変換できない

Convertは便利ですが、入力チェックを省略できるものではありません。

6. Parse・TryParse・Convertの違いと使い分け

6-1. 3つの変換方法の比較表

ParseTryParseConvertの違いをまとめると、次のようになります。

項目ParseTryParseConvert
変換成功時変換後の値を返すtrueを返し、outに値を入れる変換後の値を返す
変換失敗時例外false例外
nullの扱い例外false数値型では0
空文字の扱い例外false例外
不正文字の扱い例外false例外
実務での安全性低め高い条件付きで便利
主な用途値が保証されている変換入力値・外部データの変換汎用的な変換

実務では、まずTryParseを候補にするのが安全です。

6-2. 例外が発生する条件の違い

ParseConvertは、変換できない値に対して例外を発生させます。

C#
int.Parse("abc");        // FormatException
Convert.ToInt32("abc"); // FormatException

一方、TryParseは例外を発生させず、falseを返します。

C#
bool result = int.TryParse("abc", out int value);

Console.WriteLine(result); // false

例外は本来、予期しない異常を扱う仕組みです。ユーザー入力のミスのように日常的に起こるものは、例外ではなく条件分岐で処理する方が適しています。

6-3. null・空文字・不正文字への対応の違い

null、空文字、不正文字に対する動作を比較してみましょう。

C#
string? nullText = null;
string emptyText = "";
string invalidText = "abc";
入力値int.Parseint.TryParseConvert.ToInt32
null例外false0
""例外false例外
"abc"例外false例外
"123"123true123

Convert.ToInt32(null)0になる点は、便利でもあり危険でもあります。

未入力をエラーにしたい場合は、Convertに任せず、明示的にチェックしましょう。

6-4. 戻り値とエラーハンドリングの違い

Parseは変換結果そのものを返します。

C#
int value = int.Parse("123");

失敗時は例外処理が必要です。

C#
try
{
int value = int.Parse("abc");
}
catch (FormatException)
{
Console.WriteLine("数値形式が不正です。");
}

TryParseは成功・失敗をboolで返します。

C#
if (int.TryParse("123", out int value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("変換できません。");
}

ConvertParseと同じように変換結果を返しますが、nullの扱いが異なります。

C#
int value = Convert.ToInt32(null);
Console.WriteLine(value); // 0

6-5. 実務ではTryParseを優先すべき理由

実務では、次のような理由からTryParseを優先するのがおすすめです。

理由内容
例外を防げる不正入力でもアプリが止まりにくい
入力チェックと相性がよいエラーメッセージを表示しやすい
外部データに強いCSV、API、フォーム入力に対応しやすい
意図が明確「失敗する可能性がある変換」と分かる

特に、ユーザー入力や外部データを扱う場合は、TryParseを使うことで安全で読みやすいコードになります。

C#
string input = "100";

if (!int.TryParse(input, out int value))
{
Console.WriteLine("数値を入力してください。");
return;
}

Console.WriteLine($"変換結果: {value}");

7. 数値型同士の変換方法

7-1. intからdouble・decimalへ変換する

intからdoubledecimalへの変換は、暗黙的に行えます。

C#
int intValue = 100;

double doubleValue = intValue;
decimal decimalValue = intValue;

Console.WriteLine(doubleValue); // 100
Console.WriteLine(decimalValue); // 100

このような変換では、通常データの損失が起こりにくいため、キャストを書く必要はありません。

7-2. doubleからintへ変換する

doubleからintへ変換する場合、小数点以下が失われる可能性があるため、明示的なキャストが必要です。

C#
double doubleValue = 123.45;
int intValue = (int)doubleValue;

Console.WriteLine(intValue); // 123

キャストでは、小数点以下は0に近づく方向に切り捨てられます。

C#
Console.WriteLine((int)123.99);  // 123
Console.WriteLine((int)-123.99); // -123

四捨五入したい場合は、Math.Roundなどを使います。

C#
double value = 123.5;
int rounded = (int)Math.Round(value);

Console.WriteLine(rounded);

7-3. キャストによる明示的変換

キャストは、型を明示して変換する方法です。

C#
double value = 10.5;
int number = (int)value;

longからintのように、範囲が狭くなる変換にもキャストを使います。

C#
long longValue = 100;
int intValue = (int)longValue;

ただし、変換先の型に収まらない値をキャストすると、期待しない結果になることがあります。

C#
long longValue = 3000000000;
int intValue = (int)longValue;

Console.WriteLine(intValue); // 想定外の値になる可能性

安全に確認したい場合はcheckedを使います。

C#
long longValue = 3000000000;

try
{
int intValue = checked((int)longValue);
}
catch (OverflowException)
{
Console.WriteLine("intの範囲を超えています。");
}

7-4. Convert.ToInt32とキャストの違い

Convert.ToInt32とキャストは、小数を整数に変換するときの挙動が異なります。

C#
double value = 123.6;

int castValue = (int)value;
int convertValue = Convert.ToInt32(value);

Console.WriteLine(castValue); // 123
Console.WriteLine(convertValue); // 124

キャストは小数点以下を切り捨てます。

一方、Convert.ToInt32は丸め処理を行います。

さらに、.5のような中間値では、最も近い偶数に丸められる点にも注意が必要です。

C#
Console.WriteLine(Convert.ToInt32(2.5)); // 2
Console.WriteLine(Convert.ToInt32(3.5)); // 4

これは、一般的な「必ず0.5以上を切り上げる四捨五入」とは異なる場合があります。

7-5. 小数を整数に変換するときの丸め処理

小数を整数に変換するときは、目的に応じて方法を選びます。

処理使用する方法
小数点以下を切り捨てるキャスト、Math.Truncate
四捨五入するMath.Round
切り上げるMath.Ceiling
切り下げるMath.Floor
Convertの丸めを使うConvert.ToInt32

例です。

C#
double value = 123.45;

Console.WriteLine((int)value); // 123
Console.WriteLine(Math.Round(value)); // 123
Console.WriteLine(Math.Ceiling(value)); // 124
Console.WriteLine(Math.Floor(value)); // 123
Console.WriteLine(Math.Truncate(value)); // 123

負の数では、FloorTruncateの結果が異なる点に注意しましょう。

C#
double value = -123.45;

Console.WriteLine(Math.Floor(value)); // -124
Console.WriteLine(Math.Truncate(value)); // -123

8. 数値変換で発生するエラーと対処法

8-1. FormatExceptionの原因と対処法

FormatExceptionは、文字列が数値として解釈できない場合に発生します。

C#
int value = int.Parse("abc");

主な原因は次の通りです。

原因
数字以外の文字が含まれる"abc"
空文字""
記号が不正"12-3"
カンマや通貨記号の扱いが不適切"1,000""¥100"
小数を整数として変換しようとする"123.45"

対処法は、TryParseを使うことです。

C#
string input = "abc";

if (!int.TryParse(input, out int value))
{
Console.WriteLine("整数を入力してください。");
}

8-2. OverflowExceptionの原因と対処法

OverflowExceptionは、値が変換先の型の範囲を超えている場合に発生します。

C#
int value = int.Parse("999999999999");

intに収まらない可能性がある場合は、まずlongで受ける、またはTryParseで判定します。

C#
string input = "999999999999";

if (long.TryParse(input, out long longValue))
{
Console.WriteLine(longValue);
}
else
{
Console.WriteLine("数値が大きすぎます。");
}

intとして扱いたい場合は、範囲チェックも行います。

C#
string input = "999999999999";

if (!long.TryParse(input, out long value))
{
Console.WriteLine("数値ではありません。");
return;
}

if (value < int.MinValue || value > int.MaxValue)
{
Console.WriteLine("intの範囲を超えています。");
return;
}

int intValue = (int)value;

なお、doubleでは非常に大きな値が無限大として扱われるケースもあるため、必要に応じてdouble.IsInfinityも確認します。

C#
if (double.TryParse("1e9999", out double result))
{
if (double.IsInfinity(result))
{
Console.WriteLine("値が大きすぎます。");
}
}

8-3. ArgumentNullExceptionが関係するケース

Parsenullを渡すと、ArgumentNullExceptionが発生します。

C#
string? input = null;
int value = int.Parse(input);

TryParseであれば、nullを渡しても例外ではなくfalseになります。

C#
string? input = null;

if (int.TryParse(input, out int value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("値が入力されていません。");
}

Convert.ToInt32(null)0になります。

C#
int value = Convert.ToInt32(null);
Console.WriteLine(value); // 0

そのため、nullをエラーとして扱いたいのか、0として扱いたいのかを明確にしておくことが重要です。

8-4. 全角数字・カンマ・空白を含む文字列への対応

実務では、次のような文字列を数値変換したい場合があります。

C#
"123"
"1,000"
" 123 "
"¥1,000"

前後の空白は、TryParseで処理できる場合があります。

C#
int.TryParse(" 123 ", out int value);
Console.WriteLine(value); // 123

カンマ区切りを許可したい場合は、NumberStyles.AllowThousandsを指定します。

C#
using System.Globalization;

string input = "1,000";

bool success = int.TryParse(
input,
NumberStyles.AllowThousands,
CultureInfo.InvariantCulture,
out int value
);

Console.WriteLine(success); // true
Console.WriteLine(value); // 1000

通貨記号を含む場合は、NumberStyles.Currencyを使う方法もあります。

C#
using System.Globalization;

string input = "¥1,000";

bool success = decimal.TryParse(
input,
NumberStyles.Currency,
CultureInfo.GetCultureInfo("ja-JP"),
out decimal value
);

Console.WriteLine(success);
Console.WriteLine(value);

全角数字は、そのままでは期待通りに変換できないことがあるため、半角へ正規化してから変換するのが安全です。

C#
string input = "123";

string normalized = input
.Replace('0', '0')
.Replace('1', '1')
.Replace('2', '2')
.Replace('3', '3')
.Replace('4', '4')
.Replace('5', '5')
.Replace('6', '6')
.Replace('7', '7')
.Replace('8', '8')
.Replace('9', '9');

if (int.TryParse(normalized, out int value))
{
Console.WriteLine(value);
}

8-5. 例外を出さない安全な変換コードの書き方

例外を出さずに安全に変換する基本形は、次の通りです。

C#
string? input = "123";

if (!int.TryParse(input, out int value))
{
Console.WriteLine("数値に変換できません。");
return;
}

Console.WriteLine($"変換結果: {value}");

空文字や空白を事前にチェックしたい場合は、string.IsNullOrWhiteSpaceを組み合わせます。

C#
string? input = " ";

if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("値を入力してください。");
return;
}

if (!int.TryParse(input, out int value))
{
Console.WriteLine("整数を入力してください。");
return;
}

Console.WriteLine(value);

実務では、次の順番でチェックすると分かりやすくなります。

  1. 未入力チェック

  2. 数値形式チェック

  3. 範囲チェック

  4. 業務ルールチェック

C#
string? input = "150";

if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("年齢を入力してください。");
return;
}

if (!int.TryParse(input, out int age))
{
Console.WriteLine("年齢は整数で入力してください。");
return;
}

if (age < 0 || age > 120)
{
Console.WriteLine("年齢は0〜120の範囲で入力してください。");
return;
}

Console.WriteLine($"年齢: {age}");

9. 実務で使える数値変換のサンプルコード

9-1. テキストボックスの入力値をintに変換する

Windows FormsやWPF、ASP.NETなどでテキストボックスの値を数値に変換する場合は、TryParseを使います。

C#
string input = textBoxAge.Text;

if (!int.TryParse(input, out int age))
{
MessageBox.Show("年齢は整数で入力してください。");
return;
}

if (age < 0 || age > 120)
{
MessageBox.Show("年齢は0〜120の範囲で入力してください。");
return;
}

// 正常処理
MessageBox.Show($"入力された年齢: {age}");

Webアプリケーションでも考え方は同じです。

C#
string? input = Request.Form["quantity"];

if (!int.TryParse(input, out int quantity))
{
ModelState.AddModelError("quantity", "数量は整数で入力してください。");
return View();
}

if (quantity <= 0)
{
ModelState.AddModelError("quantity", "数量は1以上で入力してください。");
return View();
}

9-2. CSVの文字列データをdecimalに変換する

CSVで金額を扱う場合は、decimal.TryParseを使います。

C#
using System.Globalization;

string csvAmount = "1234.56";

if (!decimal.TryParse(
csvAmount,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out decimal amount))
{
Console.WriteLine("金額データが不正です。");
return;
}

Console.WriteLine($"金額: {amount}");

カンマ付きの金額を許可したい場合は、NumberStyles.Numberを指定します。

C#
using System.Globalization;

string csvAmount = "1,234.56";

bool success = decimal.TryParse(
csvAmount,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out decimal amount
);

if (success)
{
Console.WriteLine(amount);
}

CSVは外部データなので、Parseで一気に変換するより、TryParseで不正データを検出する方が安全です。

9-3. APIレスポンスの数値文字列を変換する

APIレスポンスで数値が文字列として返ってくる場合もあります。

JSON
{
"price": "1980.50",
"quantity": "3"
}

C#側では、次のように変換できます。

C#
using System.Globalization;

string priceText = "1980.50";
string quantityText = "3";

if (!decimal.TryParse(
priceText,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out decimal price))
{
Console.WriteLine("価格の形式が不正です。");
return;
}

if (!int.TryParse(quantityText, out int quantity))
{
Console.WriteLine("数量の形式が不正です。");
return;
}

decimal total = price * quantity;

Console.WriteLine($"合計: {total}");

APIでは、国や環境に依存しない形式で数値が返ることが多いため、CultureInfo.InvariantCultureを指定しておくと安全です。

9-4. 入力エラー時にメッセージを表示する

入力エラー時には、単に「エラー」と表示するのではなく、ユーザーが修正しやすいメッセージにします。

C#
string? input = Console.ReadLine();

if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("数量を入力してください。");
return;
}

if (!int.TryParse(input, out int quantity))
{
Console.WriteLine("数量は整数で入力してください。");
return;
}

if (quantity <= 0)
{
Console.WriteLine("数量は1以上で入力してください。");
return;
}

Console.WriteLine($"数量: {quantity}");

エラーメッセージは、次のように分けると親切です。

状況メッセージ例
未入力値を入力してください
数値形式ではない数値で入力してください
整数ではない整数で入力してください
範囲外1〜100の範囲で入力してください

9-5. 共通メソッド化して再利用しやすくする

同じような数値変換処理が複数箇所にある場合は、共通メソッド化すると便利です。

C#
public static bool TryConvertToInt(
string? input,
int min,
int max,
out int value,
out string errorMessage)
{
value = 0;
errorMessage = string.Empty;

if (string.IsNullOrWhiteSpace(input))
{
errorMessage = "値を入力してください。";
return false;
}

if (!int.TryParse(input, out value))
{
errorMessage = "整数で入力してください。";
return false;
}

if (value < min || value > max)
{
errorMessage = $"{min}〜{max}の範囲で入力してください。";
return false;
}

return true;
}

使用例です。

C#
if (TryConvertToInt("150", 0, 120, out int age, out string error))
{
Console.WriteLine($"年齢: {age}");
}
else
{
Console.WriteLine(error);
}

decimal用の共通メソッドも作れます。

C#
using System.Globalization;

public static bool TryConvertToDecimal(
string? input,
out decimal value,
out string errorMessage)
{
value = 0;
errorMessage = string.Empty;

if (string.IsNullOrWhiteSpace(input))
{
errorMessage = "値を入力してください。";
return false;
}

if (!decimal.TryParse(
input,
NumberStyles.Number,
CultureInfo.InvariantCulture,
out value))
{
errorMessage = "数値で入力してください。";
return false;
}

return true;
}

共通メソッド化することで、入力チェックのルールを統一でき、保守性も高くなります。

10. C#の数値変換でよくある質問

10-1. ParseとTryParseはどちらを使えばいいか

基本的には、TryParseを使うのがおすすめです。

Parseは、値が必ず正しいと分かっている場合に使います。

C#
int value = int.Parse("123");

一方、ユーザー入力やCSV、APIなど、値が不正である可能性がある場合はTryParseを使います。

C#
if (int.TryParse(input, out int value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("数値ではありません。");
}

実務では、不正な値が入る可能性を考慮して、TryParseを優先すると安全です。

10-2. Convert.ToInt32とint.Parseの違いは何か

大きな違いは、nullを渡した場合の動作です。

C#
string? text = null;

Console.WriteLine(Convert.ToInt32(text)); // 0
Console.WriteLine(int.Parse(text)); // 例外

Convert.ToInt32(null)0になりますが、int.Parse(null)は例外になります。

また、Convert.ToInt32は文字列以外の型も変換できます。

C#
double value = 123.6;
int result = Convert.ToInt32(value);

Console.WriteLine(result); // 124

ただし、不正な文字列ではConvertでも例外が発生します。

C#
Convert.ToInt32("abc"); // FormatException

10-3. 文字列がnullのときはどう変換されるか

文字列がnullの場合、変換方法によって動作が異なります。

方法結果
int.Parse(null)例外
int.TryParse(null, out value)false
Convert.ToInt32(null)0

安全に処理するなら、TryParseを使うか、事前にnullチェックを行います。

C#
string? input = null;

if (string.IsNullOrWhiteSpace(input))
{
Console.WriteLine("値が入力されていません。");
return;
}

if (int.TryParse(input, out int value))
{
Console.WriteLine(value);
}

null0として扱う仕様ならConvertでもよいですが、未入力をエラーにしたい場合は注意が必要です。

10-4. 小数を整数に変換すると四捨五入されるのか

変換方法によって異なります。

キャストでは、小数点以下が切り捨てられます。

C#
double value = 123.9;
int result = (int)value;

Console.WriteLine(result); // 123

Convert.ToInt32では丸め処理が行われます。

C#
double value = 123.9;
int result = Convert.ToInt32(value);

Console.WriteLine(result); // 124

ただし、.5の場合は最も近い偶数に丸められる点に注意してください。

C#
Console.WriteLine(Convert.ToInt32(2.5)); // 2
Console.WriteLine(Convert.ToInt32(3.5)); // 4

一般的な四捨五入を明示したい場合は、Math.Roundを使い、必要に応じて丸め方法を指定します。

C#
double value = 2.5;

int result = (int)Math.Round(
value,
MidpointRounding.AwayFromZero
);

Console.WriteLine(result); // 3

10-5. decimal・double・floatはどう使い分けるべきか

decimaldoublefloatは、扱える範囲や精度、用途が異なります。

主な用途特徴
decimal金額、会計、税計算10進数の精度を重視
double一般的な小数、科学計算範囲が広く計算が速い
floatゲーム、画像処理、大量データメモリ使用量が少ない

金額計算では、基本的にdecimalを使います。

C#
decimal price = 100.25m;
decimal tax = 0.10m;
decimal total = price * (1 + tax);

一般的な測定値や割合、座標などではdoubleを使うことが多いです。

C#
double rate = 0.12345;
double distance = 123.456;

floatは精度よりもメモリ効率を重視する場面で使われます。

C#
float x = 1.23f;

迷った場合は、金額ならdecimal、それ以外の一般的な小数ならdoubleを選ぶとよいでしょう。

まとめ

C#の数値変換には、ParseTryParseConvert、キャストなど複数の方法があります。

それぞれの特徴を整理すると、次のようになります。

方法使う場面
Parse値が必ず正しいと保証できる場合
TryParseユーザー入力や外部データなど、不正値の可能性がある場合
Convertnullを0として扱いたい場合や汎用的な変換をしたい場合
キャスト数値型同士を明示的に変換したい場合

実務で最も重要なのは、失敗する可能性がある変換ではTryParseを使うことです。

C#
if (int.TryParse(input, out int value))
{
Console.WriteLine(value);
}
else
{
Console.WriteLine("数値に変換できません。");
}

Parseはシンプルですが、不正な値で例外が発生します。Convertは便利ですが、null0にするため、未入力を見逃す可能性があります。キャストは数値型同士の変換に使えますが、小数点以下の切り捨てや桁あふれに注意が必要です。

C#の数値変換では、値の入力元、失敗時の扱い、nullや空文字の扱い、丸め処理、カルチャ差を意識することが大切です。特に、画面入力、CSV、APIレスポンスなどの外部データでは、TryParseを中心にした安全な変換処理を書くことで、例外や不具合を防ぎやすくなります。