Menu

C#で文字列をintに変換する、キャストと型変換:Parse、TryParse、Convert

C#で文字列をintに変換する方法をint.Parse、int.TryParse、Convert.ToInt32で解説します。暗黙と明示的なキャストの仕組み、doubleをキャストすると切り捨てられる理由、asとis演算子、そして"1.5"が15として解析されうる理由も扱います。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

C#は、関係のない型の間で勝手に変換することはありません。数字を含む文字列は文字列のままで、double がいつの間にか int になることもありません。変換は明示的に行い、どの手段を使うかは何を変換するかで決まります。テキストから数値へ(解析)、ある数値型から別の数値型へ(キャスト)、オブジェクトからより具体的な型へ(as、is)です。

文字列からint:Parse、TryParse、Convert

テキストを int に変える標準的な方法は3つあります。

出力:

2500
TryParse ok: 1250
TryParse failed, d = 0
42
-17

int.TryParse は bool を返し、結果を out 変数に書き込みます。失敗したときは0が設定されます。ユーザーが入力するものでは不正な入力が普通なので、入力、ファイル、クエリ文字列にはTryParseが標準的な選択です。同じメソッドはすべての数値型にあります:long.TryParse、double.TryParse、decimal.Parse などです。

不正な入力に対するそれぞれの動作

3つのメソッドの違いは、失敗の仕方だけです。

出力:

int.Parse(null) throws ArgumentNullException
Convert.ToInt32(null) = 0
int.Parse("abc") throws FormatException
int.Parse("12.5") throws FormatException
int.Parse("1,000") throws FormatException
int.Parse("9999999999") throws OverflowException
int.Parse("") throws FormatException

FormatException はおなじみの「Input string was not in a correct format」というメッセージを持ち(.NET 8以降はテキストを引用して「The input string '12.5' was not in a correct format」)、C#で最もよくある実行時エラーの1つです。"12.5" はintではなく、"1,000" もintではありません。それらを受け付けるには、decimal として解析するか、許す形式を解析器に伝えます。

出力:

1000
255
13
10

カルチャ:"1.5"が15になりうる理由

解析は既定で現在のカルチャを使い、カルチャによって区切り文字が異なります。ドイツ語や他のいくつかのヨーロッパのカルチャでは、小数点の区切りはカンマで、ピリオドは桁をまとめます。同じ文字列から異なる数値が得られます。

出力:

1.5
15
1.5

データファイル、JSON、設定など、機械が生成したものを読むコードは、解析でも書式設定でも、常に CultureInfo.InvariantCulture を渡すべきです。そうしないと、同じプログラムが開発者のマシンでは動き、別の言語に設定されたサーバーではすべての数値を読み間違えます。現在のカルチャを使うのは、人が入力したテキストや人が読むテキストに限ります。

暗黙と明示的な数値の変換

範囲を広げる変換は暗黙に行われます:int から long、int から double、float から double、int から decimal。値の大きさや小数部分を失いうる変換には、明示的なキャスト (type)value が必要です。覚えておくべき例外が1つあります。int や long から float へ、long から double への変換は、精度を失いうるにもかかわらず暗黙です。float f = 16_777_217; はコンパイルでき、16777216が格納されます。

出力:

9 -9
10
2
4
705032704
9.99
7 7.0 7

覚えておくべきことは3つです。浮動小数点から整数へのキャストは切り捨てで、丸めではありません。Convert.ToInt32(double) は銀行型丸め(半分の値は偶数の隣に)で丸めます。そして収まらない整数のキャストは、checked のコンテキストで実行されない限り何も言わずに一周し、checked の中では OverflowException を投げます(データ型を参照)。

int x = 3.7; はコンパイルエラー(CS0266: cannot implicitly convert type 'double' to 'int', an explicit conversion exists)で、これはキャストと丸めのメソッドのどちらかを選ぶようにコンパイラが求めているのです。

数値やその他の型から文字列へ

すべての型に ToString() があり、数値型は書式文字列を受け付けます。文字列補間も同じ書式設定を呼び出します。

出力:

42
000042
1234.50
1,234.50
$1,234.50
FF
1010
True
Order 000042: 1234.50

書式コード(D、F、N、C、X、P、E)や "0.00" のようなカスタムパターンは、文字列補間で扱います。

文字とブール値

出力:

7
55
7
7
A
True
False
1
False

(int)'7' は7ではなく、文字のコードである55です。数値の各桁を合計しようとする人がよくつまずく点で、'0' を引くか char.GetNumericValue を使います。bool.Parse は大文字と小文字を問わず「true」と「false」を受け付け、それ以外は受け付けません(「yes」や「1」は例外になります)。

参照の変換:キャスト、as、is

クラス型では、キャストは実行時にオブジェクトの実際の型を確認します。基底クラスへのアップキャストは暗黙です。派生クラスへのダウンキャストには明示的なキャストが必要で、オブジェクトが別のものなら InvalidCastException が投げられます。

出力:

4242
True
Card ending 4242, 50.00
InvalidCastException
5
cannot unbox int as long

型で分岐する必要があるなら、変数付きの is を優先します。確認は1回で、例外を投げることがなく、新しい変数は判定が成功した場所でしかスコープに入りません。別の型であることが大きく失敗すべきバグなら、普通のキャストを使います。ボックス化された int のケースは、object のコレクションや DataRow のセルから数値を読む人がつまずく点です。先に正確な型でボックス化を解除する((long)(int)boxed)か、任意の数値型を扱える Convert.ToInt64(boxed) を使います。

よくある質問

C#で文字列をintに変換するには?

テキストがユーザー、ファイル、ネットワークから来るなら int.TryParse(text, out int number) を使います。テキストが有効な数値でないとき、例外を投げる代わりに false を返します。不正なテキストがバグであり、例外が正しい反応なら int.Parse(text) を使います。Convert.ToInt32(text) は int.Parse と同じように動きますが、null に対しては0を返します。

int.ParseとConvert.ToInt32の違いは何ですか?

文字列に対してはほとんど同じです。どちらも "abc" のようなテキストでは FormatException を、範囲外の数値では OverflowException を投げます。違いは null で、int.Parse(null) は ArgumentNullException を投げ、Convert.ToInt32(null) は0を返します。Convert.ToInt32 は他の型(double、bool、object)も受け付け、double は切り捨てではなく最も近い偶数の整数に丸めます。

「Input string was not in a correct format」とはどういう意味ですか?

テキストが期待される形式の数値でないとき(英字、空の文字列、int を解析するときの小数点、桁区切り)に、int.Parse、double.Parse、Convert.ToInt32 が投げる FormatException のメッセージです(.NET 8以降は、テキストを引用して "The input string 'abc' was not in a correct format" となります)。例外なしで不正な入力を扱うには TryParse に切り替え、数値がどのカルチャで書かれたかを確認します。

C#でdoubleをintにキャストするには?

明示的なキャストを書きます:int n = (int)price;。キャストはゼロの方向に切り捨てるので、(int)9.99 は9、(int)-9.99 は-9です。代わりに丸めるには (int)Math.Round(price) を使います。Math.Round は既定では半分の値を最も近い偶数に丸めることに注意してください。学校で習う四捨五入にするには MidpointRounding.AwayFromZero を渡します。

C#のasとキャストの違いは何ですか?

キャスト (Dog)animal は、オブジェクトが Dog でなければ InvalidCastException を投げます。animal as Dog は代わりに null を返すので、その後にnullチェックが必要で、参照型とnull許容型にしか使えません。現代的な代替は is パターンです:if (animal is Dog dog) { ... } は1ステップで判定と変換を行います。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める