8

この投稿は C# と .Net に関するものですが、他の技術にとって価値のある情報もあります。

物心ついたときから、10 進数の解析スタイルが異なるためにアプリやゲームがクラッシュするという問題が発生していました。CAD アプリ、ライブラリから Web ページまで、非常に頻繁に発生します。無知なのか知識不足なのかわかりませんが、本当に迷惑です。

どうしたの?これについてのウィキ記事がありますが、短いです

こちらは世界中でどのような小数点記号(小数点記号)が使われているかを示した地図です。 異なる小数点記号のマップ

小数点:

  • ピリオド — 青
  • コンマ — 緑
  • 非西アラビア数字 — 赤
  • 不明 — グレー

ヨーロッパのほとんど、南アメリカでは、1 000 000,00 または 1000000,00 と書きます。時には 1.000.000,00 を「インペリアル」(青色でマーク) の反対として書き、1,000,000.00 と書きます。

先月私が遭遇したすべての問題からいくつかを紹介しましょう。

  1. 読みにくいウェブページの数: 最も視聴回数の多い YouTube 動画の 1 つを見てみましょう。それは私に 390159851 を示しています。100 万を超える数は非常に読みにくいです。3900万ですか390ですか?
  2. Mirosoft XNA for Windows Phone 7 の例: XML ファイルを解析して XNA アニメーションを生成する非常に優れたクラスがあります。

    /// <summary>
    /// Loads animation setting from xml file.
    /// </summary>
    private void LoadAnimiationFromXML()
    {
        XDocument doc = 
                  XDocument.Load("Content/Textures/AnimationsDefinition.xml");
        XName name = XName.Get("Definition");
        var definitions = doc.Document.Descendants(name);
    
    
            if (animationDefinition.Attribute("Speed") != null)
            {
                animation.SetFrameInvterval(TimeSpan.FromMilliseconds(
                    double.Parse(animationDefinition.Attribute("Speed").Value)));
            }
    

    double.Parse例外をスローします。単純な解決策の 1 つは、 を使用XmlConvert.ToDouble();または解析することInvariantCultureです。

  3. CSV ファイルを使用して入力ベクトルを CSV として保存する .Net アプリもスローします。

  4. クラス内でいくつかの解析を行う別の .Net アプリ - スロー。

では、どうすればこれを修正できますか?

  • コードのバグを修正します - 利用可能なソース コードと退屈な場合にのみ可能です。
  • データ (CVS、XML など) を変更します。可能であっても、データの変更にあまり満足していません。
  • OS のデフォルトの小数点記号を変更します - 起こりません。

これをスラブする他の方法はありますか?アプリを不変にすることはできますか? 別の環境でアプリを起動するようなものです。

PS。アプリを実行したいのですが、コードがありません。

4

5 に答える 5

6

適切に設定Thread.CurrentThread.CurrentCultureすれば、このような問題は発生しません。文化に依存しないコードの書き方については、こちらをご覧ください。

編集: コードにアクセスできない場合は、想定されるカルチャ セットを持つユーザー アカウントでアプリケーションを実行できます。すばやくアクセスするには、英語のユーザー、ドイツ語のユーザー、フランス語のユーザーを作成できます..

于 2011-06-21T16:26:21.780 に答える
1

この問題を解決する方法は他にありません。コードで修正するだけです。FxCop
を実行したい場合は、有効な CultureInfo をすべての可能なメソッドまたはメソッドに常に渡す方法をすぐに学習できます。率直に言って、デフォルトで使用されていることがわかっている場合でも、これは行うべき方法です。 常に IFormatProvider を渡すことで、他の開発者に次のように伝えます。ToString()Parse()CultureInfo.CurrentCulture

  1. ToString(CultureInfo.CurrentCulture)またはParse(whatever, CultureInfo.CurrentCulture)- これはエンドユーザーが見る、または入力できるものであるため、エンドユーザーの文化的背景を考慮する必要があります。
  2. ToString(CultureInfo.InvariantCulture)またはParse(whatever, CultureInfo.InvariantCulture)- これは内部で使用するものであり、ユーザーに表示するためのものではありません。

大変な作業のように聞こえますが、これは単に実行する必要があるものです。エンド ユーザーの CurrentCulture が書式設定プロバイダーの最適なデフォルトであると善意で決定した Microsoft の貧しい魂に感謝したいだけかもしれません... 明らかに、過去にこれを行った他のフレームワーク設計者は間違っていて、 MSは正しいですよね?このばかげた、修正不可能な間違いのために、多くの現金が蒸発しました。

于 2011-06-21T17:03:25.143 に答える
1

先月、RunKeeper の Windows Phone 7 への移植が間違っていて、光の速度を 100 000 倍に速めたと報告しました。

ずさんな場合、これらの問題に遭遇しますが、ほとんどの場合、それらは回避できます。厳密に言えば、情報は常にローカライズされた形式で表示し、保存するときにカルチャに依存しない値または基本値に変換する必要があります。このようにして、いつでも特定の文化をターゲットにすることができます。

Thread.CurrentThread.CurrentCulture多くの .NET 開発者が直面していると思われる問題は、すべての既定の解析メソッドが にフォールバックし、そのカルチャに特定の数値形式を使用し、日付やタイム ゾーンと同じであることを理解していないことです。

私が考えていることは、一連の責任を設定することです。これは、文化固有のバリアントを最初に照会し、文化に不変のフォールバックを行うものです。これらを混在させることは決してありませんが、文化に依存しないデフォルトをサポートします。これは、典型的な規則 (英語の数値形式など) に準拠している場合に機能するはずです。しかし、それは毎回正しい選択ではないかもしれません。混合数値形式の CSV ファイルを解析することが正しいことだと考えている場合は、ユーザーを教育してください。

于 2011-06-21T16:37:32.740 に答える
1

私の意見では、アプローチは次のようにする必要があります。

  1. 内部ストレージでは、数字は単なる数字です。したがって、問題は発生しません。
  2. 入力テキスト ソースを解析するときは、ソースが作成されたロケールに従って解析する必要があります。ほとんどの場合、インバリアント カルチャです。
  3. 値をユーザーに出力するときは、ユーザーが好むロケールに従ってフォーマットします。C# では、これは維持することを意味しますCurrentCulture( ではありません。理由はこちらCurrentUICultureを参照してください)。

これは比較的単純で、すべてのケースをカバーする必要があります。

これはすべて、あなたがアプリケーションの作成者である場合に当てはまります。他のアプリケーションの場合は、それぞれの開発者が自分でバグを修正する必要があります。

于 2011-06-21T16:29:57.993 に答える
1

ここに特効薬はありません。

いくつかの提案:

インバリアント カルチャは、構成ファイルに格納されている内部データを処理するときに使用できます。このようにして、マシンの文化に関係なく、独自の内部データを一貫した方法で読み書きできます。

ここを参照してください:

http://msdn.microsoft.com/en-us/library/4c5zdc6a.aspx

他の問題は、string.ToLower() のような単純なものを扱います。

現在の文化に存在しない英語の文字を小文字にしようとするまでは、無害に思えます。(EG トルコ語)

このような場合、string.ToLower() の呼び出しをカルチャ オーバーロードに置き換え、現在のカルチャまたはインバリアント カルチャを渡す必要があります (状況によって異なります)。

注意すべきいくつかの落とし穴があることは間違いありません。

于 2011-06-21T17:00:13.330 に答える