次のコードは、次のようなコンパイル時エラーをスローします
タイプ「string」を「int」に変換できません
string name = Session["name1"].ToString();
int i = (int)name;
一方、以下のコードは正常にコンパイルおよび実行されます。
string name = Session["name1"].ToString();
int i = Convert.ToInt32(name);
私が知りたいのですが:
最初のコードがコンパイル時エラーを生成するのはなぜですか?
2つのコードスニペットの違いは何ですか?
_(int)foo
_は、単に_Int32
_(C#のint
)型へのキャストです。これはCLRに組み込まれ、foo
が数値変数である必要があります(例:float
、long
など)。この意味で、キャストインに非常に似ています。 C.
_Convert.ToInt32
_は、一般的な変換関数として設計されています。キャストよりも多くのことを行います。つまり、anyプリミティブ型からint
(特にstring
の解析)に変換できます。このメソッドのオーバーロードの完全なリストを見ることができます こちらのMSDN 。
そして Stefan Steiger が言及しているように コメント内 :
また、数値レベルでは、_
(int) foo
_はfoo
(ifoo = Math.Floor(foo)
)を切り捨て、Convert.ToInt32(foo)
は half to even rounding を使用します=(x.5をifoo = Math.Round(foo)
を意味する最も近いEVEN整数に丸めます)。したがって、結果は実装だけでなく、数値的にもnot同じです。
(この行は、マージされた質問に関連しています)_(int)someString
_を使用しないでください-これは機能しません(コンパイラーはユーザーを許可しません)。
ただし、int int.Parse(string)
およびbool int.TryParse(string, out int)
(およびそれらのさまざまなオーバーロード)は公平なゲームです。
個人的に、私主にはリフレクションを扱っているときのみConvert
を使用するので、私にとっては選択肢はParse
とTryParse
です。 1つは、I expectが有効な整数になる値であり、そうでない場合に例外をスローする場合です。 2つ目は、有効な整数である場合にcheckが必要な場合です。そうである場合とそうでない場合の対処方法を決定できます。
これから引用するには Eric Lippert article :
キャストとは、2つの矛盾することを意味します。「このオブジェクトが本当にこのタイプであるかどうかを確認し、そうでない場合は投げる」と「このオブジェクトは指定されたタイプではありません。指定されたタイプに属する同等の値を見つけてください」.
ですから、1。)でやろうとしていたことは、文字列がIntであるということです。しかし、Stringはintではないため、このアサーションは失敗します。
2.)が成功する理由は、Convert.ToInt32()が文字列を解析してintを返すためです。それでも失敗する可能性があります、例えば:
Convert.ToInt32("Hello");
引数の例外が発生します。
要約すると、StringからIntへの変換はフレームワークの関心事であり、.Net型システムに暗黙的なものではありません。
明示的なキャストによって文字列をintにキャストすることはできません。 int.Parse
を使用して変換する必要があります。
Convert.ToInt32は基本的にこのメソッドをラップします。
public static int ToInt32(string value)
{
if (value == null)
{
return 0;
}
return int.Parse(value, CultureInfo.CurrentCulture);
}
あなたは、C#キャスト操作と.NET変換ユーティリティについて話している
(キャスティング)構文は、数値データ型、および「互換性のある」データ型で機能します。互換性とは、継承(つまり、ベース/派生クラス)または実装(つまり、インターフェイス)によって確立された関係があるデータ型を意味します。
キャストは、 変換演算子 が定義されている異種のデータ型間でも機能します。
一方、System.Convertクラスは、一般的な意味で物事を変換する多くの利用可能なメカニズムの1つです。これには、ある形式から別の形式に論理的に変更できる、異なる既知のデータ型間で変換するロジックが含まれています。
変換は、同様のデータ型間の変換を可能にすることで、キャストと同じ基盤の一部をカバーします。
C#言語には独自の方法がいくつかあることを忘れないでください。
そして基礎となる.NET Frameworkには、プログラミング言語とは別に、独自の方法があります。
(意図によって重複する場合があります。)
キャストは、より制限されたC#言語レベルの機能であり、System.Convertクラスを介した変換は、さまざまな種類の値を変換するための.NETフレームワークで利用可能な多くのメカニズムの1つです。
1)C#はタイプセーフな言語であり、文字列を数値に割り当てることはできません
2)2番目のケースでは、文字列が新しい変数に解析されます。あなたの場合、セッションがASP.NETセッションである場合、そこに文字列を保存し、取得するときにそれを元に戻す必要はありません
int iVal = 5;
Session[Name1] = 5;
int iVal1 = (int)Session[Name1];
.NETには、stringからintへのデフォルトのキャストはありません。これを行うには、int.Parse()またはint.TryParse()を使用できます。または、すでに行ったように、Convert.ToInt32()を使用できます。
しかし、あなたの例では、なぜToString()を実行してからそれをintに変換するのですか?次のように、単純にintをSessionに保存して取得できます。
int i = Session["name1"];
簡単な補足:さまざまな状況(たとえば、doubleを&cからInt32に変換する場合)で、これら2つを選択する際の丸めについて心配することもできます。 Convert.Int32は銀行家の丸めを使用します( [〜#〜] msdn [〜#〜] ); (int)は整数に切り捨てられます。
これは古いですが、別の違いは、二重ejがある場合、(int)は数値を切り上げないことです。5.7(int)を使用した出力は5になり、Convert.ToInt()を使用すると数値は6に丸めます。
Convert.ToInt32
return int.Parse(value、CultureInfo.CurrentCulture);
ただし、(int)は型キャストです。したがって、intに文字列をキャストできないため、(int) "2"は機能しません。しかし、Convert.ToInt32のように解析できます
違いは、最初のスニペットがキャストであり、2番目のスニペットが変換であることです。とはいえ、ここではコンパイラーのエラーが言い回しのせいで混乱を招いていると思います。 「型 'string'を 'int'にキャストできません」と言った方が良いでしょう。
これについてはすでに説明しましたが、dotnetfiddleを共有したいと思います。
算術演算を処理しており、float、decimal、doubleなどを使用している場合は、Convert.ToInt32()を使用することをお勧めします。
using System;
public class Program
{
public static void Main()
{
double cost = 49.501;
Console.WriteLine(Convert.ToInt32(cost));
Console.WriteLine((int)cost);
}
}
出力
50
49