Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.NETC#中,从未知区域性解析double的最佳方法是什么?_C#_.net_Parsing_Double - Fatal编程技术网

在.NETC#中,从未知区域性解析double的最佳方法是什么?

在.NETC#中,从未知区域性解析double的最佳方法是什么?,c#,.net,parsing,double,C#,.net,Parsing,Double,我正在使用XML文件来存储用户数据。可以从不同的本地化位置保存和加载文件。根据区域性的不同,双倍数字可以保存为“1.2345”或“12345”。差异是十进制分隔符 目前,我正在使用以下代码进行解析: private double StringToDouble(string input) { string decimalPoint = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; if (!input.Contains(

我正在使用XML文件来存储用户数据。可以从不同的本地化位置保存和加载文件。根据区域性的不同,双倍数字可以保存为“1.2345”或“12345”。差异是十进制分隔符

目前,我正在使用以下代码进行解析:

private double StringToDouble(string input)
{
    string decimalPoint = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator;

    if (!input.Contains(decimalPoint))
    {
        input = input.Replace(".", decimalPoint);
        input = input.Replace(",", decimalPoint);
    }

    return double.Parse(input);
}
上面的代码运行良好,但显然不是最好的。
您能提供更好的解决方案吗?

我建议将数字保存在固定格式中,即使用固定小数分隔符。这意味着应该执行从用户区域性到必须保存数字的区域性的转换。

如果将double作为double原语而不是字符串序列化到xml文件中,它将使用“.”保存,因此可以使用不变区域性对其进行解析

如果保存为文本,您可以尝试以下操作:

double result = double.Parse(input.Replace(",", "."), CultureInfo.InvariantCulture);
private double StringToDouble(string input)
{
    var last = input.LastIndexOfAny(new[] {',', '.'});
    var separator = last >= 0 ? input[last] : '.';
    var clone = (CultureInfo)CultureInfo.InvariantCulture.Clone();
    clone.NumberFormat.NumberDecimalSeparator = separator.ToString(CultureInfo.InvariantCulture);
    return double.Parse(input, clone);
}

请注意,对于数字为“1.234.567,89”的数千个分隔符,您仍然可能会遇到问题。

老实说,我不认为您当前的解决方案太糟糕。它不是优雅的,但是你会得到非优雅的数据。正如其他人所建议的,我想看看是否有可能以一致的格式获取XML文件,或者至少使用区域性信息保存XML文件:


这样你就不用猜了

除此之外,您还可以执行以下操作:

double result = double.Parse(input.Replace(",", "."), CultureInfo.InvariantCulture);
private double StringToDouble(string input)
{
    var last = input.LastIndexOfAny(new[] {',', '.'});
    var separator = last >= 0 ? input[last] : '.';
    var clone = (CultureInfo)CultureInfo.InvariantCulture.Clone();
    clone.NumberFormat.NumberDecimalSeparator = separator.ToString(CultureInfo.InvariantCulture);
    return double.Parse(input, clone);
}

CultureInfo.Clone
成本很高,但您可以根据分隔符的内容缓存区域性信息。这也使您可以灵活地设置不同的数千个分隔符(如果需要)。您必须假设什么是千位分隔符取决于十进制分隔符。

千位分隔符是您需要担心的问题吗?(即空格与逗号),或者它们是否都<1000并带有小数点?目前,千位分隔符没有问题。我不确定我能为现有答案添加什么。但我建议将输入作为解析/处理的一个单独步骤进行清理。(关注点分离。)如果发现其他不符合要求的信息,可以将其添加到洗涤过滤器中。如果到达不再需要的位置,可以将其从过滤器中移除。无论哪种情况,您都不必触及您的核心业务逻辑。但当然,您必须平衡这一点与增加的复杂性、性能问题等。清理的另一个优点:
ParseExact()
通常比
Parse()
快几个数量级。。。当然,它要求您的数据采用规范格式。我同意,但其中一些文件来自以自己的格式保存报价的第三方软件(外汇平台)。我也同意您的看法,但一些数据来自以自己的格式保存报价的第三方软件。谢谢。代码是有效的。我不知道CultureInfo.InvariantCulture假定“.”作为十进制分隔符。谢谢。我将在XMLs中添加一个区域性记录。是不是先翻一倍,特里帕斯。如果不成功,请为下一个double.TryParse克隆并存储定制的CultureInfo(如您所建议的)。