C# double.TryParse 与 InvariantCulture 返回意外结果

问题描述 投票:0回答:5

我正在尝试使用 NUnit 对 getprice 方法进行单元测试。我坚持将原始价格解析为双倍。我的文化信息是

en-US
,但我在这次测试中将其设置为
de-DE
。使用 numberstyles.any 和 invariantculture 进行双重解析会返回意外结果。

原始价格文化信息未知,可以是任何。此外,它将运行的服务器也是未知的,并且可以使用任何语言。

对于这次测试,我尝试了德语作为原材料价格和机器。

我尝试解析

"9,42"
,但结果是
942

[Test]
[SetCulture("de-DE")]
public void GetPrice_PriceTextWithCommaDecimal_ReturnsInvariantPrice()
{
    var rawPriceText = "9,42";
    double.TryParse(rawPriceText, NumberStyles.Any, CultureInfo.InvariantCulture, out double price);
    //parsed price result is 942

    ...
}
c# .net parsing double culture
5个回答
16
投票

从你的问题中并不清楚你的期望是什么。但是,就代码正在执行的操作而言,它完全按照您的指示执行:

  • 提供
    NumberStyles.Any
    告诉
    double.TryParse()
    允许除 AllowHexSpecifier 之外的
    any
    格式。这包括
    AllowThousands
    选项。
  • 提供
    InvariantCulture
    会导致解析使用
    ','
    字符作为千位分隔符。
  • 解析实际上并不关心千位分隔符出现在哪里。 IE。它实际上并不强制分隔符位于指示千位数字的位置。
  • 因此,当您要求它解析
"9,42"

时,该文本将使用

InvariantCulture
进行解释(即忽略当前的
de-DE
文化),
','
字符将被视为千位分隔符(即出于目的而被忽略)计算实际值),您就得到了值
942
,就像您要求的那样。

如果您不想要这个结果,则需要使用不同的参数来调用

double.TryParse()

。如果您需要关于“应该”使用哪些参数的建议,您需要解释您“做什么”想要什么。鉴于您问题中当前的信息,我们只能说您显然

想要什么论点。 ToString

TryParse

6
投票

要么是


var s = rawPrice.ToString(CultureInfo.InvariantCulture); //rawPrice becomes 9.42 double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out double price);

CultureInfo.CurrentCulture = new CultureInfo("de-DE"); var s= rawPrice.ToString(CultureInfo.CurrentCulture); //rawPrice becomes 9,42 double.TryParse(s, NumberStyles.Any, CultureInfo.CurrentCulture, out double price);


你应该把你的文化放入

TryParse
机制中。

4
投票

double.TryParse(rawPriceText, NumberStyles.Any, new CultureInfo("de"), out double price);


对于这种情况,您可以使用

CultureInfo.CurrentUICulture

而不是创建新的

CultureInfo

您将文化设置为 
de-DE


2
投票
InvariantCulture

来代替,它不会将

,
分隔符识别为小数分隔符。

使用

CurrentCulture
将会给你预期的结果。
    

我也有类似的问题。我想使用不变式在配置文件中保留双值,同时允许用户以本地格式输入数据。

这是我使用的功能。默认值允许反转任何格式错误的输入:


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.