在.NETC#中,从未知区域性解析double的最佳方法是什么?
我正在使用XML文件来存储用户数据。可以从不同的本地化位置保存和加载文件。根据区域性的不同,双倍数字可以保存为“1.2345”或“12345”。差异是十进制分隔符 目前,我正在使用以下代码进行解析:在.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(
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(如您所建议的)。