C#decimal.Parse行为

时间:2011-01-13 08:27:02

标签: c# parsing decimal

简短的问题:

为什么这些' ..... '对于解析.NET(C#)中的小数有效:

decimal res = decimal.Parse("8......15");  // returns 815
decimal res = decimal.Parse("8...15");     // returns 815
decimal res = decimal.Parse("8..15");      // returns 815

这是什么原因?

3 个答案:

答案 0 :(得分:19)

对我来说失败了。你是否有机会参加“。”文化。千位分隔符和“,”是小数点? Decimal.Parse(和类似的调用)默认使用线程的当前文化。这是否是好事是值得商榷的,但与实际行为无关:)

尝试在CultureInfo.InvariantCulture电话中指定decimal.Parse

decimal res = decimal.Parse("8......15", CultureInfo.InvariantCulture);

我相信这会表现得像你期望的那样。

答案 1 :(得分:2)

我认为这是因为解析器实际上并不关心组分隔符 - 它们与将字符串转换为小数的过程无关。

我们称他们为千位分隔符,但他们真的不是。它们是组分隔符 - 你可以每1位数,每10位数,每1位数,所以为什么不是每0位数?

有趣的是,代码已针对.NET 4进行了更改 - 这是我对Reflector的相关输出:

else
{
    if (((currencySymbol == null) || 
         ((chPtr2 = MatchChars(p, currencySymbol)) == null)) && 
        ((ansiCurrencySymbol == null) || 
         ((chPtr2 = MatchChars(p, ansiCurrencySymbol)) == null)))
    {
        break;
    }
    num |= 0x20;
    currencySymbol = null;
    ansiCurrencySymbol = null;
    p = chPtr2 - 1;
}

答案 2 :(得分:1)

我不知道为什么,但我知道它是如何工作的(十进制解析器代码部分见下文)。如果只是打开点旗并跳过所有点,我想最后一点。

    while (true)
{
    if (((ch >= '0') && (ch <= '9')) || (((options & NumberStyles.AllowHexSpecifier) != NumberStyles.None) && (((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'F')))))
    {
        //Here goes some code...
    }
    else if ((((options & NumberStyles.AllowDecimalPoint) != NumberStyles.None) && ((num & 0x10) == 0)) 
    && (((chPtr2 = MatchChars(p, currencyDecimalSeparator)) != null) || ((flag && ((num & 0x20) == 0)) 
    && ((chPtr2 = MatchChars(p, numberDecimalSeparator)) != null))))
    {
        num |= 0x10;
        p = chPtr2 - 1;
    }
}

使用反射器工具调查所有代码。