将字符串转换为double不要尊重当前数字小数点分隔符

时间:2014-10-09 11:09:44

标签: c#-4.0

我试图将表示来自不变文化的double的字符串转换为当前文化表示中的double,我关注如何使用new double表示法来使用Current的当前数字小数点分隔符培养

我使用下面的代码进行转换:

public static double ConvertToDouble(this object inputVal, bool useCurrentCulture = false)
{
    string currentSep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    string invariantSep = CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator;
    if (inputVal.GetType() == typeof(string))
    {
        if (!currentSep.Equals(invariantSep))
        {
            inputVal = (inputVal as string).Replace(invariantSep, currentSep);
        }
    }
    if (useCurrentCulture)
        return Convert.ToDouble(inputVal, CultureInfo.CurrentCulture);
    else
        return Convert.ToDouble(inputVal);
}

但上面的代码总是给我一个双"。#34;虽然我使用CurrentCulture例如法语应该给我一个带逗号的双(",")

非常感谢任何提示。

FreeDev

2 个答案:

答案 0 :(得分:2)

  

但上面的代码总是给我一个双倍的"。"作为NumberDecimalSeparator

不,它会返回doubledouble 只是一个数字。它没有NumberDecimalSeparator ......只有文化才有,并且仅在转换为字符串或从字符串转换时应用。谈论double的分隔符就像是在谈论int是十进制还是十六进制 - 没有这样的概念。 0x10和16是相同的值,由相同的位表示。

你并不是很清楚自己要做什么,但理解文本表现形式与什么之间的差异至关重要。数据值本身固有的。在解析或格式化时,您应该关心分隔符 - 但在您解析为double之后,该信息就会消失。

答案 1 :(得分:0)

根据评论和您的问题,我猜您确实希望将string转换为doubleInvariantCulture或当前文化。然后应该将此double转换为字符串,该字符串由当前文化日期时间格式信息(如NumberDecimalSeparator)格式化。

所以这个方法应该做两件事:

  1. 解析字符串以加倍
  2. 将double转换为字符串

  3. public static string ConvertToFormattedDouble(this string inputVal, IFormatProvider sourceFormatProvider = null, IFormatProvider targetFormatProvider = null)
    {
        if (sourceFormatProvider == null) sourceFormatProvider = NumberFormatInfo.InvariantInfo;
        if (targetFormatProvider == null) targetFormatProvider = NumberFormatInfo.CurrentInfo;
        if (sourceFormatProvider == targetFormatProvider)
            return inputVal; // or exception?
    
        double d;
        bool isConvertable = double.TryParse(inputVal, NumberStyles.Any, sourceFormatProvider, out d);
        if (isConvertable)
            return d.ToString(targetFormatProvider);
        else
            return null; // or whatever
    }
    

    您可以这样使用它:

    string input = "1234.567";
    string output = input.ConvertToFormattedDouble();  // "1234,567"
    

    请注意,我扩展了字符串而不是对象。在我看来,对象的扩展是一个坏主意。你用一种你几乎从不使用的方法来污染智能感知(虽然它也适用于string)。


    <强>更新

    如果你真的想沿着这条路前进并使用object的扩展名来支持任何类型的数字作为(盒装)对象或字符串,你可以试试这个扩展名:

    public static string ConvertToFormattedDouble(this object inputVal, IFormatProvider sourceFormatProvider = null, IFormatProvider targetFormatProvider = null)
    {
        if (sourceFormatProvider == null) sourceFormatProvider = NumberFormatInfo.InvariantInfo;
        if (targetFormatProvider == null) targetFormatProvider = NumberFormatInfo.CurrentInfo;
    
        if (inputVal is string)
        {
            double d;
            bool isConvertable = double.TryParse((string)inputVal, NumberStyles.Any, sourceFormatProvider, out d);
            if (isConvertable)
                return d.ToString(targetFormatProvider);
            else
                return null;
        }
        else if (IsNumber(inputVal))
        {
            decimal d = Convert.ToDecimal(inputVal, sourceFormatProvider);
            return Decimal.ToDouble(d).ToString(targetFormatProvider);
        }
        else
            return null;
    }
    
    public static bool IsNumber(this object value)
    {
        return value is sbyte
                || value is byte
                || value is short
                || value is ushort
                || value is int
                || value is uint
                || value is long
                || value is ulong
                || value is float
                || value is double
                || value is decimal;
    }
    

    用法:

    object input = 1234.56745765677656578d;
    string output = input.ConvertToFormattedDouble();  // "1234,56745765678"