2009-09-28 5 views
13

現在の環境に関係なく、アプリケーション内の特定の数値がセパレータやグループ化などなしで印刷されていることを確認したいと思います。以下の2つの方法で同じ結果が得られるようです(可能性があります)。ToString( "0")とToString(CultureInfo.InvariantCulture)

123456789.ToString("0"); 
123456789.ToString(CultureInfo.InvariantCulture); 

エッジケースやクォークがありますか?どちらが「正しい」ものでしょうか?どちらを使いますか?

私は2番目のものを使用していましたが、最近は最初のものが見つかりました。追加のusing System.Globalizationが必要ないため、使い始めました。

答えて

0

あなたは、私が個人的に最初のオプションは、あなたが持っていると思う「何に関係なく、何の書式設定」を指定しないすることを確認したいと思っている場合:

123456789.ToString("0"); 

より良いが、意図を伝達します。欠点は、使用している数値型の書式文字列が "0"にオーバーライドされている場合です。

+0

ああ、私は今あなたがフォーマット文字列を上書きできることをご存知でしたか?私はそれを調べる必要があります。 –

+0

オーバーロードについて確かですか? MSDN(http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx)によれば、「これらの標準よりも1文字だけ高い文字は、実行時にFormatExceptionをスローします。」 –

+0

これが本当かどうかはわかりませんでした。私はMSDNライブラリへの素早い移動が私に示されているのを見る:)。 –

2

私が見ているように、最初のフォーマットは、コンピュータのデフォルトカルチャを使って少なくとも1文字の数字です。 2番目は、InvariantCultureの規則に応じて数値として書式を設定します。

ボビー

+0

私が間違っている場合は私を訂正してください:123456789.ToString( "0")には、桁区切りや区切り記号などは適用されません。 –

+0

うーん...本当にそうではありません。私は現在のカルチャールールを適用する "N0"のようなフォーマットシンボルと誤っています。あなたは正しい、0は直接の書式設定なので、_any_カルチャ情報は適用されません。 誰かが123456789.ToString()を使用することもできますが、 。 – Bobby

5

二つの方法は等しくない:最初のCurrentCultureを使用しています。これは特定の文化では余分なドット/コンマにつながる可能性があります(例はありません)。

InvariantCultureを使用する場合、常に同じ書式が使用されていることが確かです。

編集:そして、CodeAnalysisを使用すると、CultureInfoを使用しないときに不平を言います。

+0

私は現在のスレッドカルチャを変更して最初のものをテストしましたが、それは影響しませんでした。私は "0"の意味:少なくとも1桁+グループ化または区切りなし。もし私がいくつかの桁区切りや区切りを持っていたければ、私は "000,000"のような何かをしなければならないと思います。 –

+2

しかし、あなたは正しいです:InvariantCultureはより明白です。 MSDNでも「...それは英語に関連していますが、どの国/地域にも関連付けられていません」と言われています。ええと、ToString(CultureInfo.InvariantCulture)についてもっと考えると、それは "G"を使ってフォーマットされた場合の数値です。 "G"はどんなグループ化も使用していないように見えるだけなので、すべてがうまく動作します。しかし、(私はちょうどそれを見て)不変の文化は、いくつかのグループが指定されています。たとえば、12345789.ToString( "N"、CultureInfo.InvariantCulture)を試してください。 –

17

回答とここでの議論に基づいて、私はさらに調査を行いました。ここで私が見つけたものです:

  • 引数なし12345678.ToString()を使用する場合、.NETはNumberFormatInfo.NegativeSign、のNumberFormatInfoの影響を受けている一般的な一般的な書式指定子「G」を使用しています。 NumberDecimalSeparator、NumberFormatInfo.NumberDecimalDigits、およびNumberFormatInfo.PositiveSignです。私には、これはどんな文化でも12345678.ToString()は常に "12345678"を生産すると言います。あなたは別の数字にしたい場合は

  • 、あなたは(カスタムフォーマット文字列を提供するために、または、もちろん)数値書式指定子「N」を使用する必要があります。数字のグループ化は "C"と "P"にも適用されます。

  • 不変培養は実際(コースの3桁によって)桁区切りと桁区切り文字を指定しません。したがって、123456789.ToString(CultureInfo.InvariantCulture)が "123456789"を生成する理由は、不変のカルチャのためではありませんが、デフォルトの一般的な数値書式指定子 "G"のためです。

だから私は、結論はそれが余分な引数についてを心配だけを使用しない完全にOKだということだと思います:

12345678.ToString() 

私はすべてのケースから、この最高だと思いますなぜなら、通常は、ToString()を呼び出す必要はありません。ほとんどの印刷/書き込み関数はあらゆる種類の引数を受け入れ、ToString()をあなたに代わって行うからです。

1

2行は異なるものです。最初の行はローカルカルチャで数値をフォーマットし、2行目はフォーマットせずにCultureInfo.InvariantCultureを使用して文字列に変換します。

この種のメソッド(ToString、ToLower ...)でCultureInfo.InvariantCultureを使用すると、その値がどのソフトウェア(データベース、別のライブラリ...)でも使用されているかどうかを確認できます。それは同じ値をもたらし、この値を取り上げることができれば、処理を続けることができます。しかし、あなたがこれを使用しない場合、他のソフトウェアはあなたの文化が何であるか把握しなければなりません。カンマで区切られた小数点の区切りを意味しましたか?

ライブラリやデータベース間で値を交換/使用し、CultureInfo.CurrentCultureを使用してアプリケーションのユーザーに表示する場合は、すべてCultureInfo.InvariantCultureを使用します。

// for softwares 
string mystring1 = 1234.ToString("0", CultureInfo.InvariantCulture); 

// for your application users 
string mystring2 = 1234.ToString("0", CultureInfo.CurrentCulture); 
1

(〜5年後...)

私はこの正確な質問を探していたが、そこには受け入れ答えはなかったとJan Zichが正しいにもかかわらず、私は一緒に少しを置くだろうと思ったので、これをテストする例。

これまでのところ、.ToString()、.ToString( "0")、および.ToString(任意のカルチャーインフォメーション)の間に違いはないと言います(整数と小数点に関する限り)

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures) 
    .Except(CultureInfo.GetCultures(CultureTypes.SpecificCultures)); 

foreach(var c in cultures){ 
    var num = (int.MinValue);/* 
    var num = (int.MaxValue);/* 
    var num = (decimal.MinValue);/* 
    var num = (decimal.MaxValue);/* 
--*/ 

    var s1 = num.ToString("0") ; 
    var s2 = num.ToString(c); 
    if(s1 != s2){ 
     var s = string.Format("{2}: {0} {1}",s1,s2,c); 
     s.Dump(); 
    } 
} 

LinqPad snippet

0

.ToString().ToString(CultureInfo.InvariantCulture)常に整数の同じ結果を与えます。

コードは以下の私のPC上で結果「0違いがを見つけ、809の文化がテスト」を与える:

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures).ToArray(); 
var numbers = new[] { 0, -1, 1, int.MinValue, int.MaxValue }; 

var diffsFound = 0; 
foreach (var culture in cultures) 
{ 
    foreach (var number in numbers) 
    { 
     var s1 = number.ToString(); 
     var s2 = number.ToString(culture); 
     if (s1 != s2) 
     { 
      Console.WriteLine($"{culture.DisplayName}: {s1} != {s2}"); 
      diffsFound++; 
     } 
    } 
} 

Console.WriteLine($"{cultures.Length} cultures tested, {diffsFound} differences found.");