文化不变的Decimal.TryParse()

Sha*_*dog 32 c# cultureinfo decimal tryparse

我正在为十进制验证器编写一个自定义字符串,需要使用忽略文化的Decimal.TryParse(即不关心输入是否包含"."或","作为小数点分隔符).这是建议的方法:

public static bool TryParse(
    string s,
    NumberStyles style,
    IFormatProvider provider,
    out decimal result
)
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚要用什么作为第三个参数.我见过的例子如下:

culture = CultureInfo.CreateSpecificCulture("en-GB");
Decimal.TryParse(value, style, culture, out number)
Run Code Online (Sandbox Code Playgroud)

所以他们创造了一种特定的文化 CultureInfo没有"CreateInvariantCulture"方法,CultureInfo.InvariantCulture不是必需的类型.什么是正确的用法?

Nay*_*ori 53

尝试这样:

decimal value;
bool b = Decimal.TryParse("0.1", NumberStyles.Any, new CultureInfo("en-US"), out value);
Run Code Online (Sandbox Code Playgroud)

最好的方法可能是使用Decimal.Parse()方法,就像传统上使用任何十进制字符串值一样.

您可以使用NumberStyles.Currency指定以货币形式读取值,这将处理任何与货币相关的值(您需要添加对System.Globalalization的引用以使用它:

using System.Globalization;
Run Code Online (Sandbox Code Playgroud)

Decimal.Parse还接受第三个参数,这将允许您明确设置IFormatProvider如果您这样选择并希望您特定的文化:

decimal value = Decimal.Parse(currency, NumberStyles.Currency, CultureInfo.InvariantCulture); //yields 15.55
Run Code Online (Sandbox Code Playgroud)


Sha*_*dog 7

我的坏人 我测试了以下代码:

        string DutchDecimal = "1,5";
        string EnglishDecimal = "1.5";
        decimal a;
        decimal b;
        Console.WriteLine(decimal.TryParse(DutchDecimal, out a));
        Console.WriteLine(a);
        Console.WriteLine(decimal.TryParse(EnglishDecimal, out b));
        Console.WriteLine(b);
        Console.Read();
Run Code Online (Sandbox Code Playgroud)

它正确解析两个字符串.似乎默认的TryParse确实是文化不变的.我认为情况并非如此,因为EnterpriseLibrary中的默认TypeConversionValidator依赖于文化,我认为它只是使用了TryParse.但是,事实证明这个默认解析器是硬编码的,以使用当前的文化.

编辑:我发现"1.5"转换为1.5,"1,5"转换为15.这对于文化不变行为实际上是正确的,所以就是这样.这整个问题显然是由于我对文化不变性如何运作的误解而产生的.

  • 解析 1,5 到 15 并不是真的正确,是吗?如果 ',' 是千位分隔符,则不允许在 10 位。我认为使用文化不变解析来解析 1,5 应该会失败。 (3认同)
  • @avl_sweden 当逗号不是小数分隔符时,假设逗号是千位分隔符是不正确的。例如,瑞典会写“1,234,567.89”,印度会写“12,34,567.89”,中国会写“123,4567.89”。数字格式并不是那么简单。我的猜测是,当逗号不是小数分隔符时,解析器会完全忽略它。 (2认同)

Dav*_*nan 5

实际上CultureInfo.InvariantCulture可以在这里使用。参数期望IFormatProvider,一个CultureInfo实现的接口。但是InvariantCulture从某种意义上说它是不变的,因为它不会随用户的设置而变化。

实际上,没有文化接受任何一个,.作为小数点分隔符-它们都是一个或另一个。您必须找到其他方法来处理可以使用这些十进制分隔符之一的数据。