5

実際のところ、数値データを生成できる複数のシステムがあり、それらはテキスト ファイルで Web サーバーに保存されています。一部のシステムでは小数点を分数区切りとして使用し、一部のシステムでは小数点のコンマを同じように使用します。

アプリケーション (ファット クライアント、.net 2.0) も、どちらの種類のシステムでも実行できます。

それで、つまずいた後、私はこれをしました:(http://pastebin.com/vhLXABDD

    public static bool HasDecimalComma;
    public static bool HasDecimalPeriod;

    public static double GetNumber(string NumberString)
    {
        if (!HasDecimalComma && !HasDecimalPeriod)
        {
            string s = string.Format("{0:0.0}", 123.123);
            if (s.Contains('.'))
            {
                HasDecimalPeriod = true;
            }
            else if (s.Contains(','))
            {
                HasDecimalComma = true;
            }
            else
            {
                throw new SystemException(string.Format("strange number format '{0}'", s));
            }
        }
        if (HasDecimalComma)
        {
            return double.Parse(NumberString.Replace('.', ','));
        }
        if (HasDecimalPeriod)
        {
            return double.Parse(NumberString.Replace(',', '.'));
        }
        throw new ArgumentException(string.Format("can't parse '{0}'", NumberString));
    }

より良い、よりエレガントな方法を提案していただけますか?

編集:

前に言及しなかったことをお詫び申し上げます。あなたの答えはその方向に傾いているため、文化の生成を数字で保存することはできません。それを「検出」しようとすることしかできません。

4

4 に答える 4

1

呼び出しサイトを変更できず、小数点記号の横に他の種類の区切り記号が存在しないことが保証されている場合は、多かれ少なかれそのメソッドを使用できます。私は提案します

  1. andHasDecimalCommaHasDecimalPeriodメソッド本体に移動 - この場合、グローバル状態はまったく必要ありません。
  2. TryParseの代わりに を使用しParseます。これは、数値に誤りがある可能性があるためです。
  3. カルチャを明示的に指定しInvariantCultureます (10 進数のピリオドがあります)。
  4. 結局、「3」は浮動小数点数であるため、コンマもピリオドも持たない数値を許可します。

したがって、これらの行に沿って何か:

///comment the method assumptions here
///otherwise the method might seem wrong
public static double GetNumber(string numberString)
{
   bool hasDecimalComma = numberString.Contains(',');
   if (hasDecimalComma)
     numberString = numberString.Replace(',', '.')
   double result;
   bool success = double.TryParse(numberString, 
                      NumberStyles.Float, 
                      CultureInfo.InvariantCulture,
                      out result);
   if (success)
     return result;
   else 
     throw new ArgumentException(
                           string.Format("can't parse '{0}'", numberString));
}

(古い答え、原則としては良いが、実際には不可能)

生成するカルチャを文字列に沿って格納し、それを使用して次の行に沿ってメソッドを呼び出すことをお勧めします ( を使用double.TryParse):

public static double GetNumber(string numberString, CultureInfo culture)
{
   double result;
   bool success = double.TryParse(numberString, 
                          NumberStyles.Float | NumberStyles.AllowThousands, 
                          culture,
                          out result);
   if (success)
      return result;
   else 
      throw new ArgumentException(
                               string.Format("can't parse '{0}'", numberString));
}
于 2013-09-02T11:06:49.150 に答える
0

一部のクライアントが文化としてペルシャ語 ( fafa-IRタグ) を使用していない限り、問題ないと思います:

// apparently, Persians use '/' as the decimal separator
var slash = CultureInfo
    .GetCultures(CultureTypes.AllCultures)
    .Where(c => 
        c.NumberFormat.NumberDecimalSeparator != "," && 
        c.NumberFormat.NumberDecimalSeparator != ".")
    .ToList();
于 2013-09-06T13:31:11.793 に答える